熊猫销售数据透视表
Posted
技术标签:
【中文标题】熊猫销售数据透视表【英文标题】:pandas pivot table of sales 【发布时间】:2017-01-14 04:36:14 【问题描述】:我有一个如下列表:
saleid upc
0 155_02127453_20090616_135212_0021 02317639000000
1 155_02127453_20090616_135212_0021 00000000000888
2 155_01605733_20090616_135221_0016 00264850000000
3 155_01072401_20090616_135224_0010 02316877000000
4 155_01072401_20090616_135224_0010 05051969277205
它代表一个客户(saleid)和他/她得到的物品(物品的upc)
我想要的是把这张表转成如下形式:
02317639000000 00000000000888 00264850000000 02316877000000
155_02127453_20090616_135212_0021 1 1 0 0
155_01605733_20090616_135221_0016 0 0 1 0
155_01072401_20090616_135224_0010 0 0 0 0
因此,列是唯一的 UPC,行是唯一的 SALEID。
我是这样读的:
tbl = pd.read_csv('tbl_sale_items.csv',sep=';',dtype='saleid': np.str, 'upc': np.str)
tbl.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 18570726 entries, 0 to 18570725
Data columns (total 2 columns):
saleid object
upc object
dtypes: object(2)
memory usage: 283.4+ MB
我做了一些步骤,但不是正确的!
tbl.pivot_table(columns=['upc'],aggfunc=pd.Series.nunique)
upc 00000000000000 00000000000109 00000000000116 00000000000123 00000000000130 00000000000147 00000000000154 00000000000161 00000000000178 00000000000185 ...
saleid 44950 287 26180 4881 1839 623 3347 7
编辑: 我使用下面的解决方案变体:
chunksize = 1000000
f = 0
for chunk in pd.read_csv('tbl_sale_items.csv',sep=';',dtype='saleid': np.str, 'upc': np.str, chunksize=chunksize):
print(f)
t = pd.crosstab(chunk.saleid, chunk.upc)
t.head(3)
t.to_csv('tbl_sales_index_converted_' + str(f) + '.csv.bz2',header=True,sep=';',compression='bz2')
f = f+1
原始文件非常大,转换后无法放入内存。 上述解决方案的问题是,当我从原始文件中读取块时,所有文件中的所有列都没有。
问题 2:有没有办法强制所有块具有相同的列?
【问题讨论】:
【参考方案1】:选项 1
df.groupby(['saleid', 'upc']).size().unstack(fill_value=0)
选项 2
pd.crosstab(df.saleid, df.upc)
设置
from StringIO import StringIO
import pandas as pd
text = """ saleid upc
0 155_02127453_20090616_135212_0021 02317639000000
1 155_02127453_20090616_135212_0021 00000000000888
2 155_01605733_20090616_135221_0016 00264850000000
3 155_01072401_20090616_135224_0010 02316877000000
4 155_01072401_20090616_135224_0010 05051969277205"""
df = pd.read_csv(StringIO(text), delim_whitespace=True, dtype=str)
df
【讨论】:
这似乎是正确的,但它可能会因为结果表的大小而引发内存错误。我可以将操作保存到文件中吗?就像每 50k 行(saleids)【参考方案2】:简单的pivot_table()
解决方案:
In [16]: df.pivot_table(index='saleid', columns='upc', aggfunc='size', fill_value=0)
Out[16]:
upc 00000000000888 00264850000000 02316877000000 02317639000000 05051969277205
saleid
155_01072401_20090616_135224_0010 0 0 1 0 1
155_01605733_20090616_135221_0016 0 1 0 0 0
155_02127453_20090616_135212_0021 1 0 0 1 0
【讨论】:
以上是关于熊猫销售数据透视表的主要内容,如果未能解决你的问题,请参考以下文章