Python 分组,不使用熊猫
我有一个csv文件,样本如下:Python 分组,不使用熊猫,python,csv,dictionary,text,reduce,Python,Csv,Dictionary,Text,Reduce,我有一个csv文件,样本如下: year product country 2018 food us 2018 drink uk 2019 food uk 2019 car japan 2018 food japan 我是否可以在不使用pandas或numpy等软件包的情况下按年份对信息进行分组? 我知道我们可以先使用标准软件包csv读取输入 f = open('text.csv') csv_f = csv
year product country
2018 food us
2018 drink uk
2019 food uk
2019 car japan
2018 food japan
我是否可以在不使用pandas或numpy等软件包的情况下按年份对信息进行分组?
我知道我们可以先使用标准软件包csv
读取输入
f = open('text.csv')
csv_f = csv.reader(f)
for row in csv_f:
////////
我的预期产出是
year product product_sum
2018 food 2
2018 drink 1
2019 food 1
2019 car 1
有多种方法可以做到这一点。使用树或简单的dict 此解决方案假定group by中的字段是相邻的。只要稍作改动,您就可以概括或探索基于树的方法来获得简洁的解决方案
f=open('text.csv'))
delim=“\t”
header=f.readline()
组_dict={}
对于f.readlines()中的l:
key=delim.join(l.split()[:2])
如果密钥不在组目录中:
组目录[键]=0
组目录[键]+=1
f2=打开('output.txt','w')
f2.写入(标题)
对于组目录项()中的k,v:
写入(delim.join([k,str(v)])+'\n')```
有多种方法可以做到这一点。使用树或简单的dict
此解决方案假定group by中的字段是相邻的。只要稍作改动,您就可以概括或探索基于树的方法来获得简洁的解决方案
f=open('text.csv'))
delim=“\t”
header=f.readline()
组_dict={}
对于f.readlines()中的l:
key=delim.join(l.split()[:2])
如果密钥不在组目录中:
组目录[键]=0
组目录[键]+=1
f2=打开('output.txt','w')
f2.写入(标题)
对于组目录项()中的k,v:
写入(delim.join([k,str(v)])+'\n')```
您可以使用来计算出现的次数
f = open('text.csv')
csv_f = csv.reader(f)
next(csv_f, None) # Ignore header row
c = collections.Counter((year, product) for year, product, country in csv_f)
print(c)
# Output: Counter({('2018', 'food'): 2, ('2018', 'drink'): 1, ('2019', 'food'): 1, ('2019', 'car'): 1})
要将其写回CSV文件,可以使用.items()
和列表理解将其转换回平面列表,并使用writerows
进行写入
with open('output.csv', 'w') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(('year', 'product', 'product_sum'))
writer.writerows([(key[0], key[1], value) for key, value in c.items()])
注意:对于Python 2,使用iteritems()
而不是items()
你可以用
reduce
来解决这个问题,但我个人认为这不是很自然,也不是很通俗。但这是怎么做到的
def reduce_func(acc, update):
year, product, country = update
acc[(year, product)] += 1
return acc
resultdict = reduce(reduce_func,
csv_f,
collections.defaultdict(lambda: 0))
print(resultdict)
# Output: defaultdict(<function <lambda> at 0x1007042f0>, {('2018', 'food'): 2, ('2018', 'drink'): 1, ('2019', 'food'): 1, ('2019', 'car'): 1})
def reduce_func(附件,更新):
年份、产品、国家=更新
acc[(年度、产品)]+=1
返回acc
结果ct=reduce(reduce_func,
csv_f,
collections.defaultdict(lambda:0))
打印(结果显示)
#输出:defaultdict(,{('2018','food'):2,('2018','drink'):1,('2019','food'):1,('2019','car'):1})
如果您不想/不能使用集合。Counter出于某种原因,我建议使用Amal TS的答案,以循环方式构建字典。您可以使用来计算出现的次数
f = open('text.csv')
csv_f = csv.reader(f)
next(csv_f, None) # Ignore header row
c = collections.Counter((year, product) for year, product, country in csv_f)
print(c)
# Output: Counter({('2018', 'food'): 2, ('2018', 'drink'): 1, ('2019', 'food'): 1, ('2019', 'car'): 1})
要将其写回CSV文件,可以使用.items()
和列表理解将其转换回平面列表,并使用writerows
进行写入
with open('output.csv', 'w') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(('year', 'product', 'product_sum'))
writer.writerows([(key[0], key[1], value) for key, value in c.items()])
注意:对于Python 2,使用iteritems()
而不是items()
你可以用
reduce
来解决这个问题,但我个人认为这不是很自然,也不是很通俗。但这是怎么做到的
def reduce_func(acc, update):
year, product, country = update
acc[(year, product)] += 1
return acc
resultdict = reduce(reduce_func,
csv_f,
collections.defaultdict(lambda: 0))
print(resultdict)
# Output: defaultdict(<function <lambda> at 0x1007042f0>, {('2018', 'food'): 2, ('2018', 'drink'): 1, ('2019', 'food'): 1, ('2019', 'car'): 1})
def reduce_func(附件,更新):
年份、产品、国家=更新
acc[(年度、产品)]+=1
返回acc
结果ct=reduce(reduce_func,
csv_f,
collections.defaultdict(lambda:0))
打印(结果显示)
#输出:defaultdict(,{('2018','food'):2,('2018','drink'):1,('2019','food'):1,('2019','car'):1})
如果您不想/不能使用集合。Counter出于某种原因,我建议使用Amal TS的答案,以循环方式构建字典。是的,当然可以。你尝试过什么吗?你是在寻找这个特定的案例还是一个通用的解决方案?@juanpa.arrivillaga我正在尝试使用reduce函数来解决这个问题。嗨@AmalTs我希望得到一个通用的解决方案。为什么?这并不是reduce的真正目的。但再说一遍,你到底试过什么?是的,当然可以。你尝试过什么吗?你是在寻找这个特定的案例还是一个通用的解决方案?@juanpa.arrivillaga我正在尝试使用reduce函数来解决这个问题。嗨@AmalTs我希望得到一个通用的解决方案。为什么?这并不是reduce的真正目的。但是,你到底试过什么?