【问题标题】:convert number to binary and store in multiple columns in pandas using python使用python将数字转换为二进制并存储在pandas的多列中
【发布时间】:2019-06-30 04:07:59
【问题描述】:

我想使用 Python 将数字转换为二进制并存储在 Pandas 的多个列中。 这是一个例子。

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


    【解决方案1】:

    如果性能很重要,请使用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 行上对其进行了基准测试,它比您提到的 for cycle 方法更快(0.5 秒对 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' 部分。

      【讨论】:

      • @jezrael,您的解决方案有效。这真的更快。我已经处理了 50K 条记录,使用您的解决方案花了将近 13 秒。 Matej 解决方案只用了不到 1 秒。我需要处理大量数据。我想追求性能。
      猜你喜欢
      • 2012-10-16
      • 1970-01-01
      • 1970-01-01
      • 2013-08-21
      • 2014-11-07
      • 2015-12-14
      • 1970-01-01
      • 2015-03-22
      • 2016-07-06
      相关资源
      最近更新 更多