我有一个熊猫数据框,其列= [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
答案 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
列中没有与之对应的值,则某些列可能会丢失。