这相当于我的csv文件;
customer,quantity
a,250
a,166
c,354
b,185
a,58
d,68
c,263
c,254
d,320
b,176
d,127
...
此 CSV 文件有 8000 个数据。我想分开"a","b","c",..."客户"列中的"z"和"数量"列。这个csv文件只是一个例子,其实客户太多了。我不知道客户姓名。我想要的是每个客户端都有自己的CSV文件。我必须使用python来做它们。
我很抱歉我的英语不好。
我认为最简单的方法是使用dict
来存储客户名称和所有相关数量:
from csv import reader, writer
with open('the_file.csv', 'r') as file_in:
csv_in = reader(file_in)
customers = {}
first_line = True
for cust, qty in csv_in:
if first_line:
first_line = False
continue
if cust not in customers:
customers[cust] = [qty]
else:
customers[cust].append(qty)
for cust in customers:
with open(f'{cust}.csv', 'w', newline='') as file_out:
csv_out = writer(file_out)
for qty in customers[cust]:
csv_out.writerow([cust, qty])
我在pandas
模块中不好,但我得到了你想要的,这段代码使用户名.csv
,并在文件中插入他/她的名称和数量。如果您遇到任何错误,您可以尝试此操作,请在评论中告诉我。注意:请尝试使用同一数据文件的副本执行此操作
# pip install pandas
import pandas as pd
data = pd.read_csv('abc.csv') # write you csv file name here.
all_customer_value = list(data['customer'])
all_customer_quantity = list(data['quantity'])
all_customer_name = set(data['customer'])
for user in all_customer_name:
with open(f'{user}.csv','w')as file:
file.write('customer,quantityn') # edited
for index,value in enumerate(all_customer_value):
with open(f'{value}.csv','a') as file:
file.write(f'{value}, {all_customer_quantity[index]}n')
如果你对 Pandas 没问题,我会在.read_csv()
创建的数据帧上使用.groupby()
(按客户分组),然后用.to_csv()
将片段写入 csv 文件(将file.csv
替换为您的输入文件名):
import pandas as pd
for customer, df in pd.read_csv("file.csv").groupby("customer"):
df.to_csv(f"{customer}.csv", index=False)
如果你想在没有 Pandas 的情况下做同样的事情,你可以使用标准库itertools
模块中的groupby()
以及标准库csv
模块中的reader
和writer
:
import csv
from operator import itemgetter
from itertools import groupby
with open("file.csv", "r") as file:
data = list(csv.reader(file))
header, data = data[0], data[1:]
key = itemgetter(0)
for customer, group in groupby(sorted(data, key=key), key=key):
with open(f"{customer}.csv", "w") as file:
writer = csv.writer(file)
writer.writerow(header)
writer.writerows(group)
如果您想避免排序,那么像 @gimix 这样的解决方案可能会更好。
我能想到的最有效的解决方案如下,其中直到最后都没有关闭任何文件(通过ExitStack()
处理),并且输入直接分类到正确的插槽中:
import csv
from contextlib import ExitStack
writers = {}
with ExitStack() as files:
reader = csv.reader(files.enter_context(open("file.csv", "r")))
header = next(reader)
for row in reader:
customer = row[0]
if customer not in writers:
fout = files.enter_context(open(f"{customer}.csv", "w"))
writers.setdefault(customer, csv.writer(fout)).writerow(header)
writers[customer].writerow(row)
这里的权衡是:没有中间数据结构,但文件处理簿记。
(我会避免使用文件打开/关闭数量可能过多的解决方案:运行时可能会显着恶化。
我对一个包含 1_000_000 行和 1_000 个客户的示例文件进行了一些计时。10次执行时间(使用timeit
):
- 沙里姆·伊克巴尔的解决方案(接受的答案):933 秒
- 熊猫版在这个答案:16秒
- Python-
groupby
这个答案中的版本:17秒 - Gimix 溶液的略微修改版本:16 秒
- 此答案的最后一个版本:11 秒
因此,如果您想最小化代码量,请使用 2。否则,请从 3 个中选择。- 5.但是不要使用1.:这是你不应该如何做的一个例子(而且,tbh,答案不应该被接受)。
PS:不要向信使开枪;)