Python 将字典中的值打印到新的csv文件
我有一个csv文件,看起来像这样Python 将字典中的值打印到新的csv文件,python,pandas,numpy,data-cleaning,Python,Pandas,Numpy,Data Cleaning,我有一个csv文件,看起来像这样 year,gender,age,country 2002,F,9-10,CO 2002,F,9-10,CO 2002,M,9-10,CO 2002,F,9-10,BR 2002,M,11-15,BR 2002,F,11-15,CO 2003,F,9-10,CO 2003,M,9-10,CO 2003,F,9-10,BR 2003,M,9-10,CO 2004,F,11-15,BR 2004,F,11-15,CO 2004,F,9-10,BR 2004,F,9-1
year,gender,age,country
2002,F,9-10,CO
2002,F,9-10,CO
2002,M,9-10,CO
2002,F,9-10,BR
2002,M,11-15,BR
2002,F,11-15,CO
2003,F,9-10,CO
2003,M,9-10,CO
2003,F,9-10,BR
2003,M,9-10,CO
2004,F,11-15,BR
2004,F,11-15,CO
2004,F,9-10,BR
2004,F,9-10,CO
我想得到如下输出文件:
year,gender,age,country,population
2002,F,9-10,CO,2
2002,M,9-10,CO,1
2002,F,9-10,BR,1
2002,M,9-10,BR,0
2002,F,11-15,CO,1
2002,M,11-15,CO,0
2002,F,11-15,BR,0
2002,M,11-15,BR,1
2003,F,9-10,CO,1
2003,M,9-10,CO,1
2003,F,9-10,BR,1
2003,M,9-10,BR,0
2003,F,11-15,CO,0
2003,M,11-15,CO,0
2004,F,9-10,CO,1
2004,M,9-10,CO,0
2004,F,9-10,BR,1
2004,M,9-10,BR,0
2004,F,11-15,CO,1
2004,M,11-15,CO,0
2004,F,11-15,BR,1
2004,M,11-15,BR,0
基本上我想打印出每年、每个年龄和每个国家的女性人数,所以年份、性别、年龄和国家将是字典的关键。此外,某些年份没有特定国家的数据,或者某些年份没有特定国家的特定年龄。例如,2003年,女性没有country CO中11-15岁年龄组的数据。在这种情况下,人口将为0。此外,有些年份根本没有具体的性别数据。例如,对于2004年,没有所有年龄和国家的男性数据,但我仍然希望将其打印在人口为0的输出文件中
下面是我编写的一些python代码,但它不起作用,我不知道如何处理丢失的数据,并在population字段中将其打印为0
import csv
import os
import sys
from operator import itemgetter, attrgetter
import math
from collections import Counter
# Create dictionary to hold the data
valDic = {}
# Read data into dictionary
with open(sys.argv[1], "r",) as inputfile:
readcsv = csv.reader(inputfile, delimiter = ',')
next(readcsv)
for line in readcsv:
key = line[0] + line[1] + line[2] + line[3]
year = line[0]
gender = line[1]
age = line[2]
country = line[3]
if key in valDic:
key = key + 1
else:
valDic[key] = [year, gender, age, country, 0] # 0s are placeholder for running sum and itemCount
inputfile.close()
newcsvfile = []
for key in valDic:
newcsvfile.append([valDic[key][0], valDic[key][1], valDic[key][2], valDic[key][3], len(valDic[key])])
newcsvfile = sorted(newcsvfile)
newcsvfile = [["year", "gender", "age", "country", "population"]]
with open(sys.argv[2], "w") as outputfile:
writer = csv.writer(outputfile)
writer.writerows(newcsvfile)
我们可以将年份、性别、年龄、国家的每个组合存储为一个元组,并将其用作字典的键。我们还维护每个值的唯一集合。我们反复研究我们所看到的每一个组合,如果没有相关数据(比如2004年,只有女性存在,但没有男性);然后我们可以为此添加“0” 演示:
导入csv
导入系统
#创建字典来保存数据
valDic={}
年,性别,年龄,国家=set(),set(),set(),set()
#把数据读入字典
打开(sys.argv[1],'r',)作为输入文件:
reader=csv.reader(输入文件,分隔符=',')
下一位(读者)
对于读取器中的行:
键=(第[0]行、第[1]行、第[2]行、第[3]行)
年份。添加(键[0])
性别。添加(键[1])
添加年龄(键[2])
country.add(键[3])
如果钥匙不在valDic中:
valDic[键]=0
valDic[键]+=1
#添加缺少的组合
对于y年:
就性别而言:
对于一个年轻人:
对于国内的c:
键=(y,g,a,c)
如果钥匙不在valDic中:
valDic[键]=0
#准备新的CSV
newcsvfile=[[“年”、“性别”、“年龄”、“国家”、“人口”]]
对于键,val已排序(valDic.items()):
newcsvfile.append([key[0],key[1],key[2],key[3],valDic[key]]))
将open(sys.argv[2],“w”,换行=”)作为输出文件:
writer=csv.writer(输出文件)
writer.writerows(newcsvfile)
产出:
year,gender,age,country,population
2002,F,11-15,BR,0
2002,F,11-15,CO,1
2002,F,9-10,BR,1
2002,F,9-10,CO,2
2002,M,11-15,BR,1
2002,M,11-15,CO,0
2002,M,9-10,BR,0
2002,M,9-10,CO,1
2003,F,11-15,BR,0
2003,F,11-15,CO,0
2003,F,9-10,BR,1
2003,F,9-10,CO,1
2003,M,11-15,BR,0
2003,M,11-15,CO,0
2003,M,9-10,BR,0
2003,M,9-10,CO,2
2004,F,11-15,BR,1
2004,F,11-15,CO,1
2004,F,9-10,BR,1
2004,F,9-10,CO,1
2004,M,11-15,BR,0
2004,M,11-15,CO,0
2004,M,9-10,BR,0
2004,M,9-10,CO,0
我会用熊猫来做这个 我可以读取所有内容并创建
DataFrame
import pandas as pd
df = pd.read_csv(sys.argv[1])
使用groupby
我可以对行进行分组和计数,以获得现有数据的population
。它以不同的顺序创建列列表,但稍后我将把它转换为新的DataFrame
,以更改列顺序并对行进行排序
groups = df.groupby(['year', 'age', 'country', 'gender'])
data = []
for index, group in groups:
data.append([*index, len(group)]) # create row with population
Usign.unique()
我可以在列中获取所有唯一值
unique_years = df['year'].unique()
unique_genders = df['gender'].unique()
unique_age = df['age'].unique()
unique_countries = df['country'].unique()
我将它们与itertools.product
一起使用,创建年份、性别、年龄、国家/地区的所有可能组合,以检查数据中缺少的组合,并将其添加到0
我可以找到以前的组。索引的现有组合
import itertools
all_indices = groups.indices
for index in itertools.product(all_years, all_age, all_countries, all_genders):
if index not in indices:
data.append([*index, 0]) # add missing row
在这之后,我拥有了所有数据,我可以转换为DataFrame
,以更改列顺序和对行排序
# create DataFrame with new values
final_df = pd.DataFrame(data, columns=['year', 'age', 'country', 'gender', 'population'])
# change columns order
final_df = final_df[['year', 'gender', 'age', 'country', 'population']]
# sort by
final_df = final_df.sort_values(['year', 'age', 'country', 'gender'], ascending=[True, False, False, True])
最后,我可以将其保存在新的csv中
final_df.to_csv(sys.argv[2], index=False)
完整的工作示例—我使用io.StringIO
来模拟内存中的文件,而不是从文件中读取—这样每个人都可以在没有完整数据的情况下复制并测试它
text = '''year,gender,age,country
2002,F,9-10,CO
2002,F,9-10,CO
2002,M,9-10,CO
2002,F,9-10,BR
2002,M,11-15,BR
2002,F,11-15,CO
2003,F,9-10,CO
2003,M,9-10,CO
2003,F,9-10,BR
2003,M,9-10,CO
2004,F,11-15,BR
2004,F,11-15,CO
2004,F,9-10,BR
2004,F,9-10,CO'''
#---------------------------------------
import pandas as pd
#df = pd.read_csv(sys.argv[1])
import io
df = pd.read_csv(io.StringIO(text))
print(df)
#---------------------------------------
groups = df.groupby(['year', 'age', 'country', 'gender'])
data = []
for index, group in groups:
data.append([*index, len(group)])
#---------------------------------------
unique_years = df['year'].unique()
unique_genders = df['gender'].unique()
unique_age = df['age'].unique()
unique_countries = df['country'].unique()
#print('years :', unique_years)
#print('genders :', unique_genders)
#print('age :', unique_age)
#print('countries:', unique_countries)
import itertools
all_indices = groups.indices
for index in itertools.product(all_years, all_age, all_countries, all_genders):
if index not in indices:
data.append([*index, 0])
#---------------------------------------
# create DataFrame with new values
final_df = pd.DataFrame(data, columns=['year', 'age', 'country', 'gender', 'population'])
# change columns order
final_df = final_df[['year', 'gender', 'age', 'country', 'population']]
# sort by
final_df = final_df.sort_values(['year', 'age', 'country', 'gender'], ascending=[True, False, False, True])
# reset index
final_df = final_df.reset_index(drop=True)
print(final_df)
# save in file
#final_df.to_csv(sys.argv[2], index=False)
final_df.to_csv('output.csv', index=False)
使用df.groupby(['year'、'genter'、'age'、'country'])
您可以计算它。您可以在开始时创建包含所有键和值的字典0。如果csv中不存在某个键,则字典中将有0。@furas您可以更具体地说明如何执行该操作吗?在真实的文件中有两个以上的国家和年龄段,我不能全部列出。我对编码还不熟悉,所以我不知道如何创建一个包含所有键的dic,正如您所说,要获得0的缺失值,您必须首先创建包含所有国家/地区、所有年龄段的列表。使用这些列表,您可以在填充字典后检查字典中是否缺少数据。或者在开始时,您可以创建字典,其中所有项都由零填充,然后从csv中添加值。所以,您必须首先只读取csv以获取所有国家和所有年龄范围,然后再次读取csv以创建字典。