可能是重复的,但我花了太多时间在这上面,现在谷歌搜索却没有任何运气。假设我有一个数据框:
import pandas as pd
data = {"letters": ["a", "a", "a", "b", "b", "b"],
"boolean": [True, True, True, True, True, False],
"numbers": [1, 2, 3, 1, 2, 3]}
df = pd.DataFrame(data)
df
Run Code Online (Sandbox Code Playgroud)
我想 1)按字母分组,2)如果布尔值中的所有值都具有相同的值,则取数字的平均值。在 RI 中会写:
library(dplyr)
df %>%
group_by(letters) %>%
mutate(
condition = n_distinct(boolean) == 1,
numbers = ifelse(condition, mean(numbers), numbers)
) %>%
select(-condition)
Run Code Online (Sandbox Code Playgroud)
这将产生以下输出:
# A tibble: 6 x 3
# Groups: letters [2]
letters boolean numbers
<chr> <lgl> <dbl>
1 a TRUE 2
2 a TRUE 2
3 a TRUE 2
4 b TRUE 1
5 b TRUE 2
6 b FALSE 3
Run Code Online (Sandbox Code Playgroud)
你会如何使用 Python pandas 来做到这一点?
我们可以使用惰性groupby和transform:
g = df.groupby('letters')
df.loc[g['boolean'].transform('all'), 'numbers'] = g['numbers'].transform('mean')
Run Code Online (Sandbox Code Playgroud)
输出:
letters boolean numbers
0 a True 2
1 a True 2
2 a True 2
3 b True 1
4 b True 2
5 b False 3
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用 np.where。当一组具有唯一值时,求均值。它不保留数字的地方。代码如下
df['numbers'] =np.where(df.groupby('letters')['boolean'].transform('nunique')==1,df.groupby('letters')['numbers'].transform('mean'), df['numbers'])
letters boolean numbers
0 a True 2.0
1 a True 2.0
2 a True 2.0
3 b True 1.0
4 b True 2.0
5 b False 3.0
Run Code Online (Sandbox Code Playgroud)
或者,在计算平均值时屏蔽条件不适用的情况。
m=df.groupby('letters')['boolean'].transform('nunique')==1
df.loc[m, 'numbers']=df[m].groupby('letters')['numbers'].transform('mean')
Run Code Online (Sandbox Code Playgroud)
由于您直接与 R 进行比较,我更愿意使用siuba而不是pandas:
from siuba import mutate, if_else, _, select, group_by, ungroup
df1 = df >>\
group_by(_.letters) >> \
mutate( condition = _.boolean.unique().size == 1,
numbers = if_else(_.condition, _.numbers.mean(), _.numbers)
) >>\
ungroup() >> select(-_.condition)
print(df1)
letters boolean numbers
0 a True 2.0
1 a True 2.0
2 a True 2.0
3 b True 1.0
4 b True 2.0
5 b False 3.0
Run Code Online (Sandbox Code Playgroud)
注意那>>是管道。我添加\是为了跳到下一行。另请注意,要引用您使用的变量_.variable
看来你的 R 代码有问题,在 R 中,你应该使用condition = all(boolean)而不是你拥有的代码。这将翻译成condition = boolean.all()Python
| 归档时间: |
|
| 查看次数: |
1434 次 |
| 最近记录: |