我正在尝试创建一个数据框,其中列与已售商品的ID相关,而行索引是购买这些商品的客户的ID。单元格应显示每个客户购买每件商品的数量。为了获得此信息,我阅读了CSV文件,其中包含客户进行的每笔交易的行。
文件被解析为frame_
变量。我使用相应列上的unique()
函数检索客户和商品ID,并使用它们创建一个新的数据框,并将这些ID作为列标题和行索引。
with open(f"{file_path}") as file:
frame_ = pd.read_csv(file, sep="\t", header=None)
customer_ids = list(frame_[customer_index].unique())
item_ids = list(frame_[item_index].unique())
frame = pd.DataFrame.from_dict(
dict.fromkeys(item_ids, dict.fromkeys(customer_ids, 0)))
下一步,我要遍历frame_
以检查每一行是否有3个值:
应将金额添加到frame.at[customer_id, item_id]
的当前值。
for index, row in frame_.iterrows():
customer = row[customer_index]
item = row[item_index]
amount = abs(float(row[2]))
frame.at[customer, item] += amount
由于我使用iterrows()
,所以此部分特别慢。
我仔细研究了一些问题,但是因为我不太清楚自己要寻找的是什么,所以找不到如何更有效地执行任务的解决方案。
感谢您的时间和任何建议。
编辑:原始文件和frame_
数据帧包含约250万行
编辑2:从frame_
添加的摘录中,“ ...”包含与此部分无关的其他信息。列标题实际上是0-8,为便于阅读,添加了“ ID”,“金额”,“ itemID”和“ customerID”:
ID ... amount ... ... itemID ... customerID ...
1 ... -5.0 ... ... 1258 ... 805214 ...
2 ... -10.0 ... ... 3658 ... 798125 ...
3 ... -7.5 ... ... 2056 ... 589012 ...
编辑3:期望的输出看起来像这样:
1258 3658 2056
805214 5.0 0 0
798125 0 10.0 0
589012 0 0 7.5
答案 0 :(得分:1)
首先准备另一列金额的绝对值(尽管我不完全了解您需要的abs
和float
-您的金额已经不是正数和数字了吗?):
import numpy as np
frame_["amount1"] = np.abs(frame_["amount"].astype(float))
然后按客户和商品索引进行汇总:
frame = frame_.groupby(["customerID", "itemID"])["amount1"].sum()
不需要显式迭代。您可以根据需要将结果转换为“宽”格式:
frame.unstack().fillna(0)
#itemID 1258 2056 3658
#customerID
#589012 0.0 7.5 0.0
#798125 0.0 0.0 10.0
#805214 5.0 0.0 0.0