python - 带有 Apply 和 Groupby 的 Lambda
问题描述
我正在尝试计算由第二列分组的熊猫数据框的列中的唯一值,并将结果作为数据框中的新列返回。
当我在以下数据帧上测试此操作时,它返回空值。
df = pd.DataFrame([('bird', 'Falconiformes', 389.0), ('bird', 'Psittaciformes', 24.0), ('mammal', 'Carnivora', 80.2), ('mammal', 'Primates', np.nan), ('mammal', 'Carnivora', 58)], index=['falcon', 'parrot', 'lion', 'monkey', 'leopard'],columns=('class', 'order', 'max_speed'))
在熊猫 0.18 中,我正在使用
df['test'] = df.groupby('class').transform('unique')
Traceback (most recent call last):
File "<ipython-input-146-283294ac8bef>", line 1, in <module>
df['test'] = df.groupby('class').transform('unique')
File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\groupby\generic.py", line 1469, in transform
raise ValueError(msg)
ValueError: 'unique' is not a valid function name for transform(name)
但我的管理员最近更新了 pandas 和 unique 不再是转换的有效函数。有一个线程建议申请 pandas 1.1.3(见讨论)。我查看了 1.1.3 的新文档并尝试使用以下内容
df['test']=df.groupby('class').apply(lambda x: x['max_speed'].unique())
df
Out[135]:
index class order max_speed test
0 falcon bird Falconiformes 389.0 NaN
1 parrot bird Psittaciformes 24.0 NaN
2 lion mammal Carnivora 80.2 NaN
3 monkey mammal Primates NaN NaN
4 leopard mammal Carnivora 58.0 NaN
但 apply 不会将值扩展到其他行,即使
df.groupby('class').apply(lambda x: x['max_speed'].unique())
Out[140]:
class
bird [389.0, 24.0]
mammal [80.2, nan, 58.0]
dtype: object
如果我尝试添加最新应用文档中提到的关键字,我会收到一条错误消息。
df['test']=df.groupby('class').apply(lambda x: x['max_speed'].unique(), result_type='expand')
Traceback (most recent call last):
File "<ipython-input-145-9b84754c6daf>", line 1, in <module>
df['test']=df.groupby('class').apply(lambda x: x['max_speed'].unique(), result_type='expand')
File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\groupby\groupby.py", line 870, in apply
return self._python_apply_general(f, self._selected_obj)
File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\groupby\groupby.py", line 892, in _python_apply_general
keys, values, mutated = self.grouper.apply(f, data, self.axis)
File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\groupby\ops.py", line 213, in apply
res = f(group)
File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\groupby\groupby.py", line 843, in f
return func(g, *args, **kwargs)
TypeError: <lambda>() got an unexpected keyword argument 'result_type'
我知道我可以将 groupby 与聚合和唯一函数一起使用,并将生成的数据帧重新合并。但我必须为几个不同的分组执行此操作,我更喜欢单行答案。
解决方案
这有点老套,但我认为它可以满足您的需求
df.groupby('class').apply(lambda d: d.assign(Test = [d['max_speed'].unique()]*len(d)))
生产
| | class | order | max_speed | Test |
|:----------------------|:--------|:---------------|------------:|:-----------------|
| ('bird', 'falcon') | bird | Falconiformes | 389 | [389. 24.] |
| ('bird', 'parrot') | bird | Psittaciformes | 24 | [389. 24.] |
| ('mammal', 'lion') | mammal | Carnivora | 80.2 | [80.2 nan 58. ] |
| ('mammal', 'monkey') | mammal | Primates | nan | [80.2 nan 58. ] |
| ('mammal', 'leopard') | mammal | Carnivora | 58 | [80.2 nan 58. ] |
诀窍是说服assign
应该d['max_speed'].unique()
在所有相关行中复制它——因为我们传递了一个长度列表,该列表对于所有条目len(d)
具有相同的元素d['max_speed'].unique()
。这d
是groupby
推荐阅读
- javascript - 快递不设置Cookie
- java - Jenkins 错误:- [错误] 读取 /home/oci/.m2/repository/org/apache-extras/beanshell/bsh/2.0b6/bsh-2.0b6.jar 时出错;无效的 LOC 标头(错误的签名)
- graphql - 弃用 ApolloServer 中的类型
- c# - StreamReader 不会从 NetworkStream 中检索所有内容(TCP 和 C#)
- javascript - 用javascript计算多个输入值
- c# - LINQ中First()和Key的区别
- r - 数字(nrowz)错误:map()函数的“长度”参数无效
- javascript - 创建 [key,value] 的多维数组,其中键唯一计数作为 JSON 对象数组中的值
- symfony - 无法生成捆绑包
- excel - 使用 VBA 跨列和行匹配数据