我是R的狂热用户,并且正在学习python。我可以在R中轻松运行的示例代码之一使我感到困惑。
这是原始数据(在R中构造):
library(tidyverse)
df <- tribble(~name, ~age, ~gender, ~height_in,
"john",20,'m',66,
'mary',NA,'f',62,
NA,38,'f',68,
'larry',NA,NA,NA
)
输出如下:
df
# A tibble: 4 x 4
name age gender height_in
<chr> <dbl> <chr> <dbl>
1 john 20 m 66
2 mary NA f 62
3 NA 38 f 68
4 larry NA NA NA
我想做三件事:
这是我在R中进行的操作(再次使用tidyverse程序包):
tmp <- df %>%
mutate_if(is.character, function(x) ifelse(is.na(x),"zz",x)) %>%
mutate_if(is.character, as.factor) %>%
mutate_if(is.numeric, function(x) ifelse(is.na(x), 0, x))
这是数据帧tmp的输出:
tmp
# A tibble: 4 x 4
name age gender height_in
<fct> <dbl> <fct> <dbl>
1 john 20 m 66
2 mary 0 f 62
3 zz 38 f 68
4 larry 0 zz 0
我熟悉Python中的if()和else()语句。我不知道是在Python中执行上述代码的正确且最易读的方式。我猜想pandas包中没有mutate_if等效项。我的问题是,我可以在python中使用哪些类似的代码来模仿tidyverse和R中的mutate_if,is.character,is.numeric和as.factor函数?
另一方面,我对代码执行的速度/效率不是很感兴趣,而是对可读性感兴趣,这就是为什么我真正喜欢tidyverse的原因。如果有任何提示或建议,我将不胜感激。
编辑1:添加代码以创建熊猫数据框
这是我用来在Python中创建数据框的代码。这可能会帮助其他人入门。
import pandas as pd
import numpy as np
my_dict = {
'name' : ['john','mary', np.nan, 'larry'],
'age' : [20, np.nan, 38, np.nan],
'gender' : ['m','f','f', np.nan],
'height_in' : [66, 62, 68, np.nan]
}
df = pd.DataFrame(my_dict)
其输出应类似:
print(df)
name age gender height_in
0 john 20.0 m 66.0
1 mary NaN f 62.0
2 NaN 38.0 f 68.0
3 larry NaN NaN NaN
答案 0 :(得分:0)
好吧,睡一觉后,我想我已经解决了。
这是我用来获取pandas数据帧并应用前面提到的类似mutate_if函数以获得相同结果的代码。
# fill in the missing values (similar to mutate_if from tidyverse)
df1 = df.select_dtypes(include=['double']).fillna(0)
df2 = df.select_dtypes(include=['object']).fillna('zz').astype('category')
df = pd.concat([df2.reset_index(drop = True), df1], axis = 1)
print(df)
name gender age height_in
0 john m 20.0 66.0
1 mary f 0.0 62.0
2 zz f 38.0 68.0
3 larry zz 0.0 0.0
# check again for the data types
df.dtypes
name category
gender category
age float64
height_in float64
dtype: object
要注意的是,我不得不“分解”原始数据框,应用更改(即,填写缺失值并更改数据类型),然后重新组合列(即,将数据框放回原处)
答案 1 :(得分:0)
一种与 tidyverse 方式一致的方式怎么样:
>>> from datar import f
>>> from datar.tibble import tribble
>>> from datar.base import NA, is_na, is_numeric, is_character, as_factor
>>> from datar.dplyr import mutate, across, where
>>> from datar.tidyr import replace_na
>>> # or if you are lazy
>>> # from datar.all import *
>>>
>>> df = tribble(
... f.name, f.age, f.gender, f.height_in,
... "john", 20, 'm', 66,
... 'mary', NA, 'f', 62,
... NA, 38, 'f', 68,
... 'larry',NA, NA, NA
... )
>>>
>>> tmp = df >> \
... mutate(across(where(is_character), replace_na, "zz")) >> \
... mutate(across(where(is_character), as_factor)) >> \
... mutate(across(where(is_numeric), replace_na, 0))
>>>
>>> tmp
name age gender height_in
<category> <float64> <category> <float64>
0 john 20.0 m 66.0
1 mary 0.0 f 62.0
2 zz 38.0 f 68.0
3 larry 0.0 zz 0.0
我是 datar 包的作者。如果您对使用有任何疑问,请随时提交问题。