我在大型数据集(1000万行,6列)上使用Pandas pivot_table
函数。由于执行时间至关重要,因此我尝试加快执行速度。目前处理整个数据集大约需要8秒钟,这很慢,我希望找到其他方法来提高速度/性能。
我当前的熊猫数据透视表:
df_pivot = df_original.pivot_table(index="industry", columns = "months",
values = ["orders", "client_name"],
aggfunc ={"orders": np.sum, "client_name": pd.Series.nunique})
df_original
包含所有数据(从CSV导入的10m行)。行业是客户的行业,月份是订单月份(一月到十二月),订单是订单数量。除订单数(categorical
数据类型)外,所有数据均转换为int
数据。最初是行业,月份和client_name是字符串。
我尝试使用pandas.DataFrame.unstack
-甚至更慢。我还尝试了Dask
。 dask pivot_table
产生了一些改进(执行时间为6秒-减少了2秒)。但是,它仍然很慢。
是否有更快的替代方法(适用于大型数据集)?也许用groupy
,crosstab
重新创建了数据透视表,...不幸的是,我根本没有其他替代方法可以工作,而且我对Python和Pandas还是很陌生...
期待您的建议。预先感谢!
更新:
我用以下方法弄清了分组方式:
df_new = df_original.groupby(["months", "industry"]).agg({"orders": np.sum, "client_name": pd.Series.nunique}).unstack(level="months").fillna(0)
现在快了大约2-3秒。还有一些选择可以进一步提高速度吗?
答案 0 :(得分:1)
将月份和行业列转换为分类列: https://pandas.pydata.org/pandas-docs/stable/user_guide/categorical.html 这样可以避免很多字符串比较。
答案 1 :(得分:0)
当您将csv文件读入df时,可以传递转换函数(通过read_csv
参数converters
),将client_name
转换为哈希并向下转换{{1 }}转换为适当的orders
类型,尤其是无符号类型。
此功能列出了类型及其范围:
int
输出:
import numpy as np
def list_np_types():
for k, v in np.sctypes.items():
for i, d in enumerate(v):
if np.dtype(d).kind in 'iu':
# only int and uint have a definite range
fmt = '{:>7}, {:>2}: {:>26} From: {:>20}\tTo: {}'
print(fmt.format(k, i, str(d),
str(np.iinfo(d).min),
str(np.iinfo(d).max)))
else:
print('{:>7}, {:>2}: {:>26}'.format(k, i, str(d)))
list_np_types()
答案 2 :(得分:0)
您可以使用稀疏矩阵。它们实施起来很快,但是有一些限制。例如:您无法在COO_matrix
上建立索引我最近需要训练一个推荐器系统(lightFM),它接受了稀疏矩阵作为输入,这使我的工作变得容易得多。实际观看:
row = np.array([0, 3, 1, 0])
col = np.array([0, 3, 1, 2])
data = np.array([4, 5, 7, 9])
mat = sparse.coo_matrix((data, (row, col)), shape=(4, 4))
>>> print(mat)
(0, 0) 4
(3, 3) 5
(1, 1) 7
(0, 2) 9
>>> print(mat.toarray())
[[4 0 9 0]
[0 7 0 0]
[0 0 0 0]
[0 0 0 5]]
如您所见,它将使用您拥有的数据的列和行自动为您创建数据透视表,并用零填充其余部分。您也可以将稀疏矩阵转换为数组和数据帧(df = pd.DataFrame.sparse.from_spmatrix(mat, index=..., columns=...)
)