我有一个熊猫DF,如下所示,我正在尝试将不同行中的值计数转置为以下格式:
COL1 COL2 COL3
C1 None None
C1 C2 None
C1 C1 None
C1 C2 C3
自
C1 C2 C3
1 0 0
1 1 0
2 0 0
1 1 1
我在这里找到了这个答案(计算数据帧每一行中系列中项目的出现次数(
这满足了我的需要,但在我的数据集(400 万行(上非常慢。我尝试使用 400,000 行来做到这一点,但它仍然没有以可接受的速度运行。
我相信这是通过大量数据集进行查找的列表,并且应用本质上是一个 for 循环。这是巨大的循环,正在减慢这个过程。这里的潜在解决方案基本上提到不使用 App,鉴于我有 C1,C2,这将使这里的执行变得乏味......我的列表中有 C100 和 10 个垂直列来验证计数。关于我可以在这里尝试什么来提高性能的任何提示?
这是下面的代码:
df_store = df.apply(pd.Series.value_counts, axis=1)[list_lookup].fillna(0)
这就是为什么我们通常不使用apply
df.stack().str.get_dummies().sum(level=0).drop('None',1)
Out[157]:
C1 C2 C3
0 1 0 0
1 1 1 0
2 2 0 0
3 1 1 1
或者做Counter
from collections import Counter
pd.DataFrame([ Counter(x) for x in df.values]).drop('None',1)
Out[170]:
C1 C2 C3
0 1 NaN NaN
1 1 1.0 NaN
2 2 NaN NaN
3 1 1.0 1.0
如果你想要更快的解决方案,你需要使用numpy。使用 numpy 中的独热编码并将 ndarray 结果分配给数据帧。根据我的%timeit
,它比Counter
解决方案快约6倍。缺点是您需要提前知道要编码的值,这些值在您的情况下是C1
、C2
、C3
....C100
encode_val = np.array(['C1', 'C2', 'C3'])
encode_arr = (df.values[...,None] == encode_val).astype(int).sum(1)
Out[237]:
array([[1, 0, 0],
[1, 1, 0],
[2, 0, 0],
[1, 1, 1]])
pd.DataFrame(encode_arr, columns=encode_val)
Out[238]:
C1 C2 C3
0 1 0 0
1 1 1 0
2 2 0 0
3 1 1 1