我将世界银行千年发展目标中的大量数据设为CSV。数据显示如下:
Country Code Country Name Indicator
ABW Aruba % Forest coverage
ADO Andorra % Forest coverage
AFG Afghanistan % Forest coverage
...
ABW Aruba % Literacy rate
ADO Andorra % Literacy rate
AFG Afghanistan % Literacy rate
...
ABW Aruba % Another indicator
ADO Andorra % Another indicator
AFG Afghanistan % Another indicator
该文件目前为8.2MB。我打算为这些数据编写一个Web界面,我想按国家/地区分割数据,这样我就可以发出ajax请求,这样我就可以为每个国家加载一个单独的CSV。
我迷失在如何以编程方式或使用任何工具执行此操作。我不一定需要Python,但这是我最了解的。我不一定需要一个完整的脚本,一般指针如何解决这个问题。
我正在使用的原始数据源位于:
答案 0 :(得分:4)
您可以使用Python csv module和itertools.groupby 以下示例在Python 2.7.1上进行了测试 编辑:更新了对问题添加的新信息的帐户答案。
import csv, itertools as it, operator as op
csv_contents = []
with open('yourfile.csv', 'rb') as fin:
dict_reader = csv.DictReader(fin) # default delimiter is comma
fieldnames = dict_reader.fieldnames # save for writing
for line in dict_reader: # read in all of your data
csv_contents.append(line) # gather data into a list (of dicts)
# input to itertools.groupby must be sorted by the grouping value
sorted_csv_contents = sorted(csv_contents, key=op.itemgetter('Country Name'))
for groupkey, groupdata in it.groupby(sorted_csv_contents,
key=op.itemgetter('Country Name')):
with open('slice_{:s}.csv'.format(groupkey), 'wb') as fou:
dict_writer = csv.DictWriter(fou, fieldnames=fieldnames)
dict_writer.writeheader() # new method in 2.7; use writerow() in 2.6-
dict_writer.writerows(groupdata)
其他说明:
答案 1 :(得分:4)
awk -F "," 'NF>1 && NR>1 {print $0 >> ("data_" $1 ".csv"); close("data_" $1 ".csv")}' data.csv
这将创建名为data_ABW
等的新文件,其中包含适当的信息。 NR>1
部分跳过标题行。然后,对于每一行,将整行($0
)附加到名为Data_$1
的文件,其中$1
替换为第一列中的文本那条线。最后,close
语句确保没有太多打开的文件。如果你没有这么多国家,你可以摆脱这个并显着提高命令的速度。
在回答下面@ Lenwood的评论时,要在每个输出文件中包含标题,您可以这样做:
awk -F "," 'NR==1 {header=$0}; NF>1 && NR>1 {if(! files[$1]) {print header >> ("data_" $1 ".csv"); files[$1]=1}; print $0 >> ("data_" $1 ".csv"); close("data_" $1 ".csv")}' data.csv
(您可能必须逃避感叹号......)第一个新部件NR==1 {header=$0};
只将输入文件的第一行存储为变量header
。然后,另一个新的部分if(! files[$1]) ... files[$1]=1};
使用关联数组files
来跟踪它是否已将标头放入给定文件中,如果没有,则将其放在那里。
请注意,这会附加文件,因此如果这些文件已经存在,则只会添加它们。因此,如果在主文件中获得新数据,则可能需要在再次运行此命令之前删除其他文件。
(如果不明显,如果您希望将文件命名为data_Aruba
,则可以将$1
更改为$2
。)
答案 2 :(得分:2)
使用pandas
Python data analysis library非常简单:
from pandas.io.parsers import read_csv
df = read_csv(input_file, header=1, sep='\t', index_col=[0,1,2])
for (country_code, country_name), group in df.groupby(level=[0,1]):
group.to_csv(country_code+'.csv')
$ for f in *.csv ; do echo $f; cat $f; echo; done
ABW.csv
Country Code,Country Name,Indicator
ABW,Aruba,% Forest coverage
ABW,Aruba,% Literacy rate
ABW,Aruba,% Another indicator
ADO.csv
Country Code,Country Name,Indicator
ADO,Andorra,% Forest coverage
ADO,Andorra,% Literacy rate
ADO,Andorra,% Another indicator
AFG.csv
Country Code,Country Name,Indicator
AFG,Afghanistan,% Forest coverage
AFG,Afghanistan,% Literacy rate
AFG,Afghanistan,% Another indicator
答案 3 :(得分:1)
在shell脚本中。
首先,awk '{print $1}' | sort | uniq > code.lst
会为您提供国家/地区代码列表。然后,您可以遍历国家/地区代码并使用grep选择与代码匹配的所有youfilename.csv
行。
for c in `ls code.lst` do
grep $c youfilename.csv > youfilename_$c.csv
done