Answers:
给定一个示例数据框df
为:
a,b
1,2
2,3
3,4
4,5
您想要的是:
df['a'] = df['a'].apply(lambda x: x + 1)
返回:
a b
0 2 2
1 3 3
2 4 4
3 5 5
apply
切勿在这种情况下使用
apply
使用内部循环,该循环比矢量化函数要慢得多,例如df.a = df.a / 2
(请参阅Mike Muller答案)。
对于更好使用的单列map()
,像这样:
df = pd.DataFrame([{'a': 15, 'b': 15, 'c': 5}, {'a': 20, 'b': 10, 'c': 7}, {'a': 25, 'b': 30, 'c': 9}])
a b c
0 15 15 5
1 20 10 7
2 25 30 9
df['a'] = df['a'].map(lambda a: a / 2.)
a b c
0 7.5 15 5
1 10.0 10 7
2 12.5 30 9
map()
比apply()
单列更好?
df['file_name'] = df['Path'].map(lambda a: os.path.basename(a))
尽管给定的响应是正确的,但是它们修改了初始数据帧,这并不总是令人满意的(并且,如果OP要求示例“使用apply
”,那么他们可能想要一个返回新数据帧的版本,就像apply
这样)。
可以使用assign
:这可能assign
对现有列有效,因为文档指出(重点是我的):
将新列分配给DataFrame。
返回一个新对象,该对象具有除新列之外的所有原始列。重新分配的现有列将被覆盖。
简而言之:
In [1]: import pandas as pd
In [2]: df = pd.DataFrame([{'a': 15, 'b': 15, 'c': 5}, {'a': 20, 'b': 10, 'c': 7}, {'a': 25, 'b': 30, 'c': 9}])
In [3]: df.assign(a=lambda df: df.a / 2)
Out[3]:
a b c
0 7.5 15 5
1 10.0 10 7
2 12.5 30 9
In [4]: df
Out[4]:
a b c
0 15 15 5
1 20 10 7
2 25 30 9
请注意,该函数将传递给整个数据框,而不仅是要修改的列,因此您需要确保在lambda中选择正确的列。
如果您真的很关心apply函数的执行速度,并且有庞大的数据集需要处理,则可以使用swifter加快执行速度,以下是在swifter上实现pandas数据框的示例:
import pandas as pd
import swifter
def fnc(m):
return m*3+4
df = pd.DataFrame({"m": [1,2,3,4,5,6], "c": [1,1,1,1,1,1], "x":[5,3,6,2,6,1]})
# apply a self created function to a single column in pandas
df["y"] = df.m.swifter.apply(fnc)
这将使您所有的CPU内核都能计算结果,因此比正常的应用功能要快得多。尝试让我知道它是否对您有用。
让我尝试使用日期时间并考虑空值或空白的复杂计算。我正在减少30年的datetime列,并使用apply
方法以及lambda
转换datetime格式。Line if x != '' else x
将照顾所有空白或相应的空值。
df['Date'] = df['Date'].fillna('')
df['Date'] = df['Date'].apply(lambda x : ((datetime.datetime.strptime(str(x), '%m/%d/%Y') - datetime.timedelta(days=30*365)).strftime('%Y%m%d')) if x != '' else x)