如何根据索引、列名和单元格本身为每个单元格运行函数



我有一个像这样的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=0number 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

最新更新