来自 tidyverse 的 mutate_if 的等效 Python 代码

Nik*_*Nik 5 python r data-science

我是一个狂热的 R 用户,并且正在学习 Python。我可以在 R 中轻松运行的示例代码之一让我在 Python 中感到困惑。

这是原始数据(在 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
)
Run Code Online (Sandbox Code Playgroud)

其输出如下所示:

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
Run Code Online (Sandbox Code Playgroud)

我想做三件事:

  1. 我想用值“zz”替换作为字符的列中的 NA 值
  2. 我想用值 0 替换数值列中的 NA 值
  3. 我想将字符列转换为因子。

这是我在 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))
Run Code Online (Sandbox Code Playgroud)

这是数据帧 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
Run Code Online (Sandbox Code Playgroud)

我熟悉 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)
Run Code Online (Sandbox Code Playgroud)

输出应该是类似的:

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
Run Code Online (Sandbox Code Playgroud)

Nik*_*Nik 1

好吧,睡了一觉后,我想我已经弄清楚了。

这是我用来获取 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
Run Code Online (Sandbox Code Playgroud)

问题是我必须“分解”原始数据框,应用更改(即填充缺失值并更改数据类型),然后重新组合列(即将数据框重新组合在一起)。