複数の列があり、ヘッダーのない1つのCSVデータがあります。
5,-3,0
3,2,5
-2,4,4
0,2,1
2,-1,-2
それから最初の列から始めて単一の列に置き換えたいと思います。予想される出力は次のとおりです。
5
3
-2
0
2
-3
2
4
2
-1
0
5
4
1
-2
この問題を解決する方法を知っている人はいますか?
私がしたことは、Excel式を使用することでした。=INDEX($A$1:$C$4,1+INT((ROW(A1)-1)/COLUMNS($A$1:$C$4)),MOD(ROW(A1)-1+COLUMNS($A$1:$C$4),COLUMNS($A$1:$C4))+1)
単一の列で終わりますが、最初の行から始まります。
スクリプトを使用するなど、より高速な方法を探しています。
答え1
入力ファイルが完全に大きくなく(たとえば、数百万のフィールドを含む数百万行)、メモリに入ることができると仮定して、すべてのUnixシステムのすべてのシェルでawkを使用してください。
$ awk -F',' '
{ for (i=1; i<=NF; i++) a[NR,i]=$i }
END { for (i=1; i<=NF; i++) for (j=1; j<=NR; j++) print a[j,i] }
' file
5
3
-2
0
2
-3
2
4
2
-1
0
5
4
1
-2
答え2
awk
Gnuを使用する場合のもう1つのアプローチdatamash
は,
separa-t
または
datamash transpose -t, < file
5,3,-2,0,2
-3,2,4,2,-1
0,5,4,1,-2
,
その後、パイプを接続して次のものに交換できます。\n
tr
datamash transpose -t, < file | tr ',' '\n'
5
3
-2
0
2
-3
2
4
2
-1
0
5
4
1
-2
答え3
このitertools
モジュールとその関数を使用して、イテレータをリンクchain
して順次印刷できます。
python3 -c '
import sys, itertools as it
fs,rs = ",","\n"
with open(sys.argv[1]) as f:
L = []
for l in f:
F = l.rstrip(rs).split(fs)
if not len(L):
L += [[] for i in range(0,len(F))]
for nc,e in enumerate(F):
L[nc].append(e)
for x in it.chain(*L): print(x)
' file
出力:-
5
3
-2
0
2
-3
2
4
2
-1
0
5
4
1
-2