数转换为二进制,并存储在多个列中使用python大熊猫

问题描述 投票:3回答:2

我想一个数字转换为二进制和存储在多个列中使用Python大熊猫。下面是一个例子。

df = pd.DataFrame([['a', 1], ['b', 2], ['c', 0]], columns=["Col_A", "Col_B"])

for i in range(0,len(df)):
    df.loc[i,'Col_C'],df.loc[i,'Col_D'] = list( (bin(df.loc[i,'Col_B']).zfill(2) ) )

我想转换为二进制,并将其存储在多个列中的数据帧。数转换为二进制后,输出必须包含2位。这是工作的罚款。

问:如果我的数据集包含成千上万的记录,我可以看到的性能差异。如果我想提高上面代码的性能我们怎么办呢?我试着用下面一行代码,它并没有为我工作。

df[['Col_C','Col_D']] = list( (bin(df['Col_B']).zfill(2) ) )
python pandas dataframe binary
2个回答
3
投票

如果性能是重要的,使用numpythis solution

d = df['Col_B'].values
m = 2
df[['Col_C','Col_D']]  = pd.DataFrame((((d[:,None] & (1 << np.arange(m)))) > 0).astype(int))
print (df)
  Col_A  Col_B  Col_C  Col_D
0     a      1      1      0
1     b      2      0      1
2     c      0      0      0

性能(约1000倍的速度):

df = pd.DataFrame([['a', 1], ['b', 2], ['c', 0]], columns=["Col_A", "Col_B"])


df = pd.concat([df] * 1000, ignore_index=True)

In [162]: %%timeit
     ...: df[['Col_C','Col_D']] = df['Col_B'].apply(lambda x: pd.Series(list(bin(x)[2:].zfill(2))))
     ...: 
609 ms ± 14.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [163]: %%timeit
     ...: d = df['Col_B'].values
     ...: m = 2
     ...: df[['Col_C','Col_D']]  = pd.DataFrame((((d[:,None] & (1 << np.arange(m)))) > 0).astype(int))
     ...: 
618 µs ± 26.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

2
投票

apply是你正在寻找的方法。

df[['Col_C','Col_D']] = df['Col_B'].apply(lambda x: pd.Series(list(bin(x)[2:].zfill(2))))

是卓有成效的。

我基准它上3000行和它比为周期方法你提到(0.5秒VS 3秒)快。但一般的速度不会快很多,因为它仍然需要单独申请该功能的每一行。

from time import time
start = time()
for i in range(0,len(df)):
    df.loc[i,'Col_C'],df.loc[i,'Col_D'] = list( (bin(df.loc[i,'Col_B'])[2:].zfill(2) ) )
print(time() - start)
# 3.4339962005615234

start = time()
df[['Col_C','Col_D']] = df['Col_B'].apply(lambda x: pd.Series(list(bin(x)[2:].zfill(2))))
print(time() - start)
# 0.5619983673095703

注:我使用python 3,所以如bin(1)返回'0b1',因此我用bin(x)[2:]摆脱'0b'部分。

© www.soinside.com 2019 - 2024. All rights reserved.