例如,我的数据框如下所示。
>>> df
CATX CATY CATZ
0 A G AAA
1 B H BBB
2 C I AAA
3 B J CCC
4 A G BBB
5 B H DDD
6 D K EEE
7 E L FFF
我想根据列表中提供的值在df上添加新列。例如,对于CATZ,我有一个列表['AAA', 'BBB']
,我需要考虑这个列表来指示obervation是1或0,例如
>>> df
CATX CATY CATZ AAA BBB
0 A G AAA 1 0
1 B H BBB 0 1
2 A I AAA 1 0
3 B J CCC 0 0
4 A H BBB 0 1
5 B H DDD 0 0
6 D K EEE 0 0
7 E L FFF 0 0
这与pd.get_dummies
略有不同,因为get_dummies会考虑整个数据框/列上的所有可能值(或k-1值)。目前,我正在做的是遍历列表并执行每行的申请。
for catz_item in catz_list:
df[catz_item] = df.apply(lambda x: 1 if x.CATZ == catz_item else 0, axis=1)
除了迭代列表之外还有其他方法吗(因为这个循环有点慢)。为了使它更复杂,我也使用基于某个列表的CATX和CATY的组合来做到这一点,例如[[' A',' G'],[& #39; A',' H'],[' B'' H']]。
---编辑---
使用CATX / CATY
组合输出>>> df
CATX CATY CATZ AAA BBB AG AH BH
0 A G AAA 1 0 1 0 0
1 B H BBB 0 1 0 0 1
2 C I AAA 1 0 0 0 0
3 B J CCC 0 0 0 0 0
4 A G BBB 0 1 1 0 0
5 B H DDD 0 0 0 0 1
6 D K EEE 0 0 0 0 0
7 E L FFF 0 0 0 0 0
我现在使用的代码如下所示
catxy_list = [['A', 'G'], ['A', 'H'], ['B', 'H']]
for catxy_item in catxy_list:
df[catxy_item[0] + catxy_item[1]] = df.apply(lambda x: 1 if x.CATX == catxy_item[0] and x.CATY == catxy_item[1] else 0, axis=1)
答案 0 :(得分:3)
对于涉及CATZ
的第一位,您可以使用where
/ mask
+ get_dummies
-
v = df.CATZ.where(df.CATZ.isin(['AAA', 'BBB'])).str.get_dummies()
或者,
v = df.CATZ.mask(~df.CATZ.isin(['AAA', 'BBB'])).str.get_dummies()
接下来,对于您的“复杂查询”,最后使用numpy广播进行astype
转换 -
# initial values to compare
i = np.array([['A', 'G'], ['A', 'H'], ['B', 'H']])
# perform broadcasted comparison with `i` and convert the result to OHEs
j = (df.iloc[:, :-1].values[:, None] == i).all(2).astype(int)
# load the result into a dataframe with the appropriate column names
j = pd.DataFrame(j, columns=list(map(''.join, i)))
“复杂查询”的另一个较慢但更节省内存的选项是循环遍历每个类别并找到OHE:
ohe = []
for x, y in [['A', 'G'], ['A', 'H'], ['B', 'H']]:
# generate OHEs for each pair of elements per category
s = df.CATX.eq(x) & df.CATY.eq(y) # s = df[['CATX', 'CATY']].isin([x, y]).all(1)
s.name = ''.join([x, y])
ohe.append(s)
# concatenate the intermediate results
j = pd.concat(ohe, 1).astype(int)
最后,您可以使用df
将v
,j
和concat
加载到新数据框中。
pd.concat([df, v, j], 1)
CATX CATY CATZ AAA BBB AG AH BH
0 A G AAA 1 0 1 0 0
1 B H BBB 0 1 0 0 1
2 C I AAA 1 0 0 0 0
3 B J CCC 0 0 0 0 0
4 A G BBB 0 1 1 0 0
5 B H DDD 0 0 0 0 1
6 D K EEE 0 0 0 0 0
7 E L FFF 0 0 0 0 0
答案 1 :(得分:2)
In [403]: df.join(df.CATZ.str.get_dummies())
Out[403]:
CATX CATY CATZ AAA BBB CCC DDD EEE FFF
0 A G AAA 1 0 0 0 0 0
1 B H BBB 0 1 0 0 0 0
2 C I AAA 1 0 0 0 0 0
3 B J CCC 0 0 1 0 0 0
4 A G BBB 0 1 0 0 0 0
5 B H DDD 0 0 0 1 0 0
6 D K EEE 0 0 0 0 1 0
7 E L FFF 0 0 0 0 0 1
或:
In [410]: df.join(df.CATZ[df.CATZ.isin(['AAA','BBB'])].str.get_dummies(), how='left').fillna(0)
Out[410]:
CATX CATY CATZ AAA BBB
0 A G AAA 1.0 0.0
1 B H BBB 0.0 1.0
2 C I AAA 1.0 0.0
3 B J CCC 0.0 0.0
4 A G BBB 0.0 1.0
5 B H DDD 0.0 0.0
6 D K EEE 0.0 0.0
7 E L FFF 0.0 0.0
答案 2 :(得分:2)
pd.crosstab(df.index,df.CATZ)[['AAA','BBB']]
Out[66]:
CATZ AAA BBB
row_0
0 1 0
1 0 1
2 1 0
3 0 0
4 0 1
5 0 0
6 0 0
7 0 0
pd.concat([df,pd.crosstab(df.index,df.CATZ)[['AAA','BBB']]],1)
Out[68]:
CATX CATY CATZ AAA BBB
row_0
0 A G AAA 1 0
1 B H BBB 0 1
2 C I AAA 1 0
3 B J CCC 0 0
4 A G BBB 0 1
5 B H DDD 0 0
6 D K EEE 0 0
7 E L FFF 0 0
答案 3 :(得分:1)
认为您需要两个np.where
。
df["AAA"] = np.where(df["CATZ"] == "AAA", 1, 0)
df["BBB"] = np.where(df["CATZ"] == "BBB", 1, 0)
当标签很多时,这可能会很慢!