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
我想将该函数应用于列B
和D
。 (将其应用于完整的 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 数据框列
如何将 pandas get_dummies 函数应用于有效数据集?