особенность пересечения в пандах - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть 2 столбца в пандах. DF:

col_A     col_B
 0         1
 0         0
 0         1
 0         1
 1         0
 1         0
 1         1

Я хочу создать новые столбцы для каждого значения комбинации col_A и col_B, аналогично get_dummies (), но единственное изменение - здесь яя пытаюсь использовать комбинацию столбцов

Пример OP - В этом столбце значение Col_A равно 0, а col_B равно 1:

col_A_0_col_B_1

   1
   0
   1
   1
   0
   0
   0

В настоящее время я использую iterrows () для итерациичерез каждую строку, чтобы проверить значение, а затем изменить

Существует ли обычный подход панды более короткий для достижения этой цели.

Ответы [ 5 ]

0 голосов
/ 03 декабря 2018

Вы можете использовать pandas ~ для логического выражения not, в сочетании с 1 и 0, равными true и false.

df['col_A_0_col_B_1'] = ~df['col_A'] & df['col_B']
0 голосов
/ 03 декабря 2018

Преобразование логических цепочек в целые числа:

df['col_A_0_col_B_1'] = ((df['col_A']==0)&(df['col_B']==1)).astype(int)

Для повышения производительности:

df['col_A_0_col_B_1'] = ((df['col_A'].values==0)&(df['col_B'].values==1)).astype(int)

Производительность : зависит от количества строк и 0,1 значения:

np.random.seed(343)
#10k rows
df = pd.DataFrame(np.random.choice([0,1], size=(10000, 2)), columns=['col_A','col_B'])
#print (df)

In [92]: %%timeit
    ...: df['col_A_0_col_B_1'] = ((df['col_A']==0)&(df['col_B']==1)).astype(int)
    ...: 
870 µs ± 44.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [93]: %%timeit
    ...: df['col_A_0_col_B_1'] = ((df['col_A'].values==0)&(df['col_B'].values==1)).astype(int)
    ...: 
201 µs ± 3.29 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [94]: %%timeit
    ...: df['col_A_0_col_B_1'] = pd.Series((df.col_A == 0) & (df.col_B == 1), dtype='uint')
    ...: 
833 µs ± 12.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [95]: %%timeit
    ...: df['col_A_0_col_B_1'] = np.where((df['col_A']==0)&(df['col_B']==1), 1, 0)
    ...: 
956 µs ± 242 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)


In [96]: %%timeit
    ...: df['col_A_0_col_B_1'] = pd.Series([a == 0 and b == 1 for a, b in zip(df.col_A, df.col_B)], dtype='uint')
    ...: 
1.61 ms ± 57.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [97]: %%timeit
    ...: df['col_A_0_col_B_1'] = 0
    ...: df.loc[(df.col_A == 0) & (df.col_B==1),'col_A_0_col_B_1'] = 1
    ...: 
3.07 ms ± 68.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
0 голосов
/ 03 декабря 2018

Если я правильно понял, вы могли бы сделать что-то вроде этого:

import pandas as pd
data = [[0, 1],
        [0, 0],
        [0, 1],
        [0, 1],
        [1, 0],
        [1, 0],
        [1, 1]]

df = pd.DataFrame(data=data, columns=['col_A', 'col_B'])
df['col_A_0_col_B_1'] = pd.Series([a == 0 and b == 1 for a, b in zip(df.col_A, df.col_B)], dtype='uint')
print(df)

Выход

   col_A  col_B  col_A_0_col_B_1
0      0      1                1
1      0      0                0
2      0      1                1
3      0      1                1
4      1      0                0
5      1      0                0
6      1      1                0

Или как альтернатива:

df = pd.DataFrame(data=data, columns=['col_A', 'col_B'])
df['col_A_0_col_B_1'] = pd.Series((df.col_A == 0) & (df.col_B == 1), dtype='uint')
print(df)
0 голосов
/ 03 декабря 2018

Вы можете использовать np.where

df['col_A_0_col_B_1'] = np.where((df['col_A']==0)&(df['col_B']==1), 1, 0)
0 голосов
/ 03 декабря 2018

Сначала создайте свой столбец и присвойте ему, например, 0 для False

df['col_A_0_col_B_1'] = 0

Затем с помощью loc вы можете отфильтровать, где col_A == 0 и col_B == 1, а затем назначить 1в новый столбец df.loc[(df.col_A == 0) & (df.col_B==1),'col_A_0_col_B_1'] = 1

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