преобразовать число в двоичный файл и хранить в нескольких столбцах в пандах с помощью Python - PullRequest
0 голосов
/ 06 февраля 2019

Я хочу преобразовать число в двоичное и хранить в нескольких столбцах в Pandas, используя 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) ) )

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Если важна производительность, используйте numpy с этим решением :

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)
0 голосов
/ 06 февраля 2019

apply - это метод, который вы ищете.

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

делает свое дело.

Я протестировал его на 3000 строк, и он быстрее, чем метод цикла, который вы упомянули (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' части.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...