我有一个像这样的DataFrame:
Name GoogleMinutes FacebookMinutes
Alice 10 2
Bob 15 3
Chuck 40 10
我想为每个单元格运行一个签名为func(cell_value,name,site_minutes)
的函数。
换句话说。我想为每个索引、列名和值运行一个函数。
我该怎么做?我试着申请,但没有成功。
编辑:
应用程序的非工作示例:
p = PersonDataProvider()
s = SMDataProvider()
df.apply(lambda x: p.get_wealthness(x.index) * s.get_ticket(x.column) * x)
第2版:一个重要的免责声明是,尽管没有在示例中显示,但我有未知数量的列。
你能检查一下这是否适合你吗:
import pandas as pd
def main():
df = pd.DataFrame(
{'Name': ['Alice', 'Bob', 'Chuck', 'pete'], 'GoogleMinutes': [10, 15, 40, 4], 'FacebookMinutes': [2, 3, 10, 7]})
for a in range(df.shape[0]):
cell_value = a
name = df['Name'][a]
site_minutes = (df['GoogleMinutes'][a], df['FacebookMinutes'][a])
func1(cell_value, name, site_minutes)
def func1(cell_value, name, site_minutes):
print(cell_value, name, site_minutes)
return None
if __name__ == '__main__':
main()
看起来您需要对代码进行两个简单的修改:
a( 指定轴(1或行(
b( 将"index"更改为"name"。
像这样:
names = ['Alice', 'Bob', 'Chuck']
vals = [[10,2],[15,3], [40,10]]
col_names = ['GoogleMinutes', 'FacebookMinutes']
tst = pd.DataFrame(vals, index=names, columns=col_names)
tst['result'] = tst.apply(lambda x: ' '.join((x.name, str(x.GoogleMinutes), str(x.FacebookMinutes))) , axis=1)
解决方案
通常,您可以使用pandas.DataFrame.applymap
来按元素应用您的函数。
import pandas as pd
# df is your dataframe
# df.applymap(lambda x: func(x))
prepare_dataframe(df, axis=0).applymap(lambda cell: func(*cell))
但是,您的用例略有不同。因此,在使用.applymap()
之前,可以使用自定义函数prepare_dataframe()
对数据帧进行预处理
代码实现-详细示例
下面的代码片段是在GoogleColab上运行的,使用axis=0
和number of rows > number of columns
似乎更快。
%time prepare_dataframe(df, axis=0).applymap(lambda cell: func(*cell))
# CPU times: user 5.02 ms, sys: 0 ns, total: 5.02 ms
# Wall time: 4.77 ms
# Or
%time prepare_dataframe(df, axis=1).applymap(lambda cell: func(*cell))
# CPU times: user 13.5 ms, sys: 1 ms, total: 14.5 ms
# # Wall time: 23 ms
输出:
| x | y
--------------------------------------------
0 | Out: (0, 'x', 0) | Out: (0, 'y', -5)
1 | Out: (1, 'x', 1) | Out: (1, 'y', -1)
2 | Out: (2, 'x', 2) | Out: (2, 'y', 5)
3 | Out: (3, 'x', 3) | Out: (3, 'y', 13)
4 | Out: (4, 'x', 4) | Out: (4, 'y', 23)
自定义函数
def prepare_dataframe(df, axis=0):
# apply along axis = 0 or 1
# axis = 0 is faster
dff = df.copy()
index = dff.index
columns = dff.columns
nrows, ncols = dff.shape
if axis==1:
dff = dff.T
for idx in index:
dff[idx] = tuple(zip([idx]*ncols, columns, df.loc[idx].values))
dff = dff.T
else:
for col in columns:
dff[col] = tuple(zip(index, [col]*nrows, df[col].values))
return dff
# This is the dummy cell level function
def func(index=0, column='A', value=0):
return f'Out: {(index, column, value)}'
func()
# Out: (0, 'A', 0)
备注
在您的情况下,func()
将如下所示:
p = PersonDataProvider()
s = SMDataProvider()
def func(index=0, column='A', value=0):
return p.get_wealthness(index) * s.get_ticket(column) * value
伪数据
import numpy as np
import pandas as pd
x = np.arange(5)
y = x**2 + 3*x - 5
df = pd.DataFrame({'x': x, 'y': y})
print(df)
# x y
# 0 0 -5
# 1 1 -1
# 2 2 5
# 3 3 13
# 4 4 23
参考文献
- 文档-
pandas.DataFrame.applymap