Pandas:如何将函数应用于不同的列

Posted

技术标签:

【中文标题】Pandas:如何将函数应用于不同的列【英文标题】:Pandas: How to apply a function to different columns 【发布时间】:2015-12-11 20:54:33 【问题描述】:

假设这是我的功能:

def function(x):
    return x.str.lower()

这是我的 DataFrame (df)

   A         B     C       D 
0  1.67430   BAR  0.34380  FOO 
1  2.16323   FOO -2.04643  BAR
2  0.19911   BAR -0.45805  FOO
3  0.91864   BAR -0.00718  BAR
4  1.33683   FOO  0.53429  FOO
5  0.97684   BAR -0.77363  BAR

我想将该函数应用于列BD。 (将其应用于完整的 DataFrame 不是答案,因为它会在数值列中产生 NaN 值)。

这是我的基本想法:df.apply(function, axis=1)

但我无法理解如何选择不同的列来应用该函数。我已经尝试过按数字位置、名称等进行索引的各种方式。

我花了很多时间阅读这方面的内容。这不是其中任何一个的直接副本:

How to apply a function to two columns of Pandas dataframe

Pandas: How to use apply function to multiple columns

Pandas: apply different functions to different columns

Python Pandas: Using 'apply' to apply 1 function to multiple columns

【问题讨论】:

尽量避免使用apply。如果您不确定是否需要使用它,则可能不需要。我建议看看When should I ever want to use pandas apply() in my code?。 【参考方案1】:

只需从 df 中子选择列,通过忽略 axis 参数,我们按列而不是按行操作,这将是显着的,因为您在这里的行多于列:

df[['B','D']].apply(function)

这将针对每一列运行你的函数

In [186]:
df[['B','D']].apply(function)

Out[186]:
     B    D
0  bar  foo
1  foo  bar
2  bar  foo
3  bar  bar
4  foo  foo
5  bar  bar

您还可以过滤 df 以仅获取字符串 dtype 列:

In [189]:
df.select_dtypes(include=['object']).apply(function)

Out[189]:
     B    D
0  bar  foo
1  foo  bar
2  bar  foo
3  bar  bar
4  foo  foo
5  bar  bar

时间

按列与按行:

In [194]:    
%timeit df.select_dtypes(include=['object']).apply(function, axis=1)
%timeit df.select_dtypes(include=['object']).apply(function)

100 loops, best of 3: 3.42 ms per loop
100 loops, best of 3: 2.37 ms per loop

但是对于明显更大的 dfs(按行),第一种方法的扩展性会更好

【讨论】:

这很棒。理想情况下,我想这样做inplace 可以这么说而不是子集。现在使用您的答案很简单:df[['B','D']] = df[['B','D']].apply(function) 很高兴听到,如果我的回答解决了您的问题,请接受它【参考方案2】:

Apply 不是就地,它返回一个新的数据帧,所以问题是您能否一次性返回完整的数据帧。 而且你可以做到,但它很丑(它可能会稍微快一点):

df.apply(lambda x: x.str.lower() if x.name in ['B', 'D'] else x)

如果要对所有字符串列执行此操作,只需检查 dtype。

【讨论】:

好消息。使用我的实际数据,我将 7 种不同的 str 方法应用于列,因此最好使用函数。不过以后会记得的。 您可以将x.str.lower() 替换为function(x)【参考方案3】:

用于就地编辑的按列应用功能:

In [194]: df = pd.DataFrame("A": ["FOO","BAAR","FOO"], "B": ["FOO","BAR" , "FOO"])

In [195]: df.loc[:,["A","B"]].apply(lambda col : col.str.lower(), axis = 0) # axis= 0, Default in pandas 
Out[195]: 
      A    B
0   foo  foo
1  baar  bar
2   foo  foo

按行应用功能进行就地编辑(如果需要):

In [201]: df.loc[:,["A","B"]].apply(lambda row : row.str.lower(), axis = 1)
Out[201]: 
      A    B
0   foo  foo
1  baar  bar
2   foo  foo

使用按列和按行应用函数的其他有用操作:

# For column-wise operation using apply function:
In [224]: df = pd.DataFrame("A": ["FOO","BAAR","FOO"], "B": ["FOO","BAR" , "FOO"])

In [225]: df.loc[:,["A","B"]].apply(lambda col : col.str.lower() + "_" + "cool" + "_" + df["B"])
Out[225]: 
               A             B
0   foo_cool_FOO  foo_cool_FOO
1  baar_cool_BAR  bar_cool_BAR
2   foo_cool_FOO  foo_cool_FOO

#Note only second element from each column is taken as an argument for lambda function, so NaN for others:
In [226]: df.loc[:,["A","B"]].apply(lambda col : col[1:2].str.lower() + "_"+ "cool" + "_" + df["B"])
Out[226]: 
               A             B
0            NaN           NaN
1  baar_cool_BAR  bar_cool_BAR
2            NaN           NaN


#For Row-wise operation (row[0] & row[1] points to first and second element of each row, 
#or can be called as row["A"] $ row["B"] respectively ):
In [207]: df.loc[:,["A","B"]].apply(lambda row : row["B"].lower() + "_" + row["A"].lower() , axis = 1)
Out[207]: 
0     foo_foo
1    bar_baar
2     foo_foo
dtype: object

In [208]: df.loc[:,["A","B"]].apply(lambda row : row[1].lower() + "_" + row[0].lower() , axis = 1)
Out[208]: 
0     foo_foo
1    bar_baar
2     foo_foo
dtype: object

#Here, row[1] indicates second element of each row, i.e row["B"] :
In [235]: df.loc[:,["A","B"]].apply(lambda row : row.str.lower() + "_"+ row[1], axis = 1)
Out[235]: 
          A        B
0   foo_FOO  foo_FOO
1  baar_BAR  bar_BAR
2   foo_FOO  foo_FOO

【讨论】:

【参考方案4】:

就地编辑原始列的简洁语法:

df[["A", "B"]] = df[["A","B"]].apply(lambda x: x.str.lower())

另外,将新列添加到原始数据框:

df[["new_col1", "new_col2"]] = df[["A","B"]].apply(lambda x: x.str.lower())

【讨论】:

以上是关于Pandas:如何将函数应用于不同的列的主要内容,如果未能解决你的问题,请参考以下文章

将不同的函数应用于按名称选择函数的数据框的列

如何将 lambda 函数正确应用到 pandas 数据框列

python pandas-将带有两个参数的函数应用于列

如何将 pandas get_dummies 函数应用于有效数据集?

在 Pandas 中使用 group by 时如何将“first”和“last”函数应用于列?

重新采样 MultiIndexed Pandas DataFrame 并将不同的函数应用于列