python - apply(lambda x: ...) 当值是系列或数据帧时应用于字典值的函数

python - apply(lambda x: ...) function applied to dictionary value when value is a Series or a dataframe

我正在尝试对作为数据框的字典值使用 apply(lambda x: ...) 函数,但出现 ValueError: The truth value of a Series is ambiguous。使用 a.empty、a.bool()、a.item()、a.any() 或 a.all()。我知道这适用于数据框列。但我想知道是否有办法在字典值上使用它。我做错了什么?

import pandas as pd
df = pd.DataFrame({'Gender':['M','M','M','F','F','O1','O2'],
                   'A1':[2,4,8,7,6,4,5],'A2':[2,4,8,7,6,4,5],
                   'B1':[5,8,9,7,5,6,3]})
df
#>   Gender  A1  A2  B1
0      M   2   2   5
1      M   4   4   8
2      M   8   8   9
3      F   7   7   7
4      F   6   6   5
5     O1   4   4   6
6     O2   5   5   3
    
dct = {}
for cat in ['Gender','A','B']:
    dct[cat] = df[[c for c in df.columns if c.startswith(cat)]]
dct
#> {'Gender':   Gender
 0      M
 1      M
 2      M
 3      F
 4      F
 5     O1
 6     O2,
 'A':    A1  A2
 0   2   2
 1   4   4
 2   8   8
 3   7   7
 4   6   6
 5   4   4
 6   5   5,
 'B':    B1
 0   5
 1   8
 2   9
 3   7
 4   5
 5   6
 6   3}

## apply
g = dct['Gender'].apply(lambda x: 'Other' if x not in ['M','W'] else x]

#> ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

期望输出:

  Gender
0      M
1      M
2      M
3      F
4      F
5     Other
6     Other

问题:

  1. 如何将 apply(lambda x: ...) 函数传递给字典键的值(系列或数据框列)? 可以吗?

您可以直接使用pd.Series.str.fullmatch here. Pandas has has many str methods可用杠杆。

m = df['Gender'].str.fullmatch(r'[^MF]')
df.loc[m, 'Gender'] = 'Other'

print(df)
#   Gender  A1  A2  B1
# 0      M   2   2   5
# 1      M   4   4   8
# 2      M   8   8   9
# 3      F   7   7   7
# 4      F   6   6   5
# 5  Other   4   4   6
# 6  Other   5   5   3

你可以试试

dct['Gender']['Gender'].apply(lambda x: 'Other' if x not in ['M','W'] else x)
# Output:
0        M
1        M
2        M
3    Other
4    Other
5    Other
6    Other
Name: Gender, dtype: object

dct['Gender'] 访问整个值(此处为数据帧)

type(dct['Gender'])
#> pandas.core.frame.DataFrame

dct['Gender']['Gender'] 访问数据框中作为值的列。然后可以在其上使用 apply() 函数。

type(dct['Gender']['Gender'])
#> pandas.core.series.Series

文档:
pandas.Series.apply
对 Series 的值调用函数。

我无法使用来自 Ch3steR 答案的 fullmatch 的单行解决方案(可能是不同的版本?)

df.loc[~df.Gender.isin(['M', 'F']),'Gender'] = 'Others'