根据另一列的值更新熊猫数据框中的一列的更快方法

时间:2019-02-11 23:38:15

标签: python pandas numpy dataframe

我有一个熊猫数据框,其列= [A,B,C,D,... I,Z]。数据帧中大约有800,000行,并且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 :(得分:1)

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 integer array indexing生成 所需的列标签。 (下面解释'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'] by concatenating 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列中没有与之对应的值,则某些列可能会丢失。