Более быстрый способ обновления столбца во фрейме данных Pandas на основе значения другого столбца. - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть кадр данных pandas со столбцами = [A, B, C, D, ... I, Z].В кадре данных около ~ 80000 строк, и столбцы A, B, C, D, ..., у меня есть значение 0 для всех этих строк.Z имеет значение между [0, 9].Я пытаюсь обновить значение x-го столбца для всех строк во фрейме данных, где x - текущее значение Z. Если значение x равно 0, игнорировать.Фрейм данных выглядит так:

    A    B    C    D  ...  Z
0   0    0    0    0  ...  9
1   0    0    0    0  ...  1
2   0    0    0    0  ...  2
3   0    0    0    0  ...  3    

Это то, что у меня есть до сих пор.

cols = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']  
for index, row in df.iterrows():
            if row['Z'] != 9:
                df.loc[index, cols[int(row['Z'])]] = 1

Это слишком медленно и приводит к тому, что скрипт перестает выполняться на полпути.Есть ли более быстрый или лучший способ сделать это?Я попытался посмотреть np.where и np.apply, но я не могу понять синтаксис.Это то, что я пытался с помощью np.apply -

df.iloc[what goes here?] = df['Z'].apply(lambda x: 1 if x != 9)

Желаемый вывод для приведенного выше образца - -

    A    B    C    D  ...  Z
0   0    0    0    0  ...  9
1   0    1    0    0  ...  1
2   0    0    1    0  ...  2
3   0    0    0    1  ...  3 

1 Ответ

0 голосов
/ 12 февраля 2019
import numpy as np
import pandas as pd
cols = np.array(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'temp'])
df = pd.DataFrame(columns=cols[:-1])
df['Z'] = [9,1,2,3,1,5,4]
df = df.fillna(0)
df.update(pd.get_dummies(cols[df['Z']]))
print(df)

доходность

   A  B  C  D  E  F  G  H  I  Z
0  0  0  0  0  0  0  0  0  0  9
1  0  1  0  0  0  0  0  0  0  1
2  0  0  1  0  0  0  0  0  0  2
3  0  0  0  1  0  0  0  0  0  3
4  0  1  0  0  0  0  0  0  0  1
5  0  0  0  0  0  1  0  0  0  5
6  0  0  0  0  1  0  0  0  0  4

У Pandas есть функция pd.get_dummies , которая делает именно то, что вы хотите:

In [274]: pd.get_dummies(['A','C','B','D'])
Out[274]: 
   A  B  C  D
0  1  0  0  0
1  0  0  1  0
2  0  1  0  0
3  0  0  0  1

Сделав cols массив NumPy, вы можете использовать Индексирование целочисленного массива NumPy для генерации желаемых меток столбцов.(Назначение столбца 'temp' поясняется ниже):

In [276]: cols[df['Z']]
Out[276]: array(['temp', 'B', 'C', 'D', 'B', 'F', 'E'], dtype='<U3')

Чтобы get_dummies генерировал этот DataFrame:

In [277]: pd.get_dummies(cols[df['Z']])
Out[277]: 
   B  C  D  E  F  temp
0  0  0  0  0  0     1
1  1  0  0  0  0     0
2  0  1  0  0  0     0
3  0  0  1  0  0     0
4  1  0  0  0  0     0
5  0  0  0  0  1     0
6  0  0  0  1  0     0

df.update(other) копирует не-NaN значения изother DataFrame в df.Поскольку df не имеет столбца, помеченного temp, значения в этом столбце игнорируются.


В качестве альтернативы можно создать df путем объединения df['Z'] с pd.get_dummies(cols[df['Z']]):

import numpy as np
import pandas as pd
cols = np.array(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'temp'])
df = pd.DataFrame({'Z':[9,1,2,3,1,5,4]})

df = pd.concat([pd.get_dummies(cols[df['Z']]), df['Z']], axis=1)
df = df.drop('temp', axis=1)
print(df)

возвращает

   B  C  D  E  F  Z
0  0  0  0  0  0  9
1  1  0  0  0  0  1
2  0  1  0  0  0  2
3  0  0  1  0  0  3
4  1  0  0  0  0  1
5  0  0  0  0  1  5
6  0  0  0  1  0  4

Обратите внимание, что некоторые столбцы могут отсутствовать, если в столбце Z нет соответствующего ему значения.

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