2017-06-15 67 views
0

我正在尝试将函数应用于数据框的每一行。棘手的部分是该函数为每个处理后的行返回一个新的数据帧。假设这个数据框的列可以很容易地从处理过的行中派生出来。Python:将函数应用到Pandas DataFrame的每一行并返回**新数据框**

最后结果应该是所有这些数据帧(每个处理的行1个)连接起来。我故意不提供示例代码,因为最简单的解决方案建议将会执行,只要“棘手”的部分得到满足。

我花了数小时试图挖掘文档和计算器以找到解决方案。像往常一样,熊猫文档是没有实际的例子,除了最简单的操作,我无法弄清楚。我也确保不会错过任何重复的问题。非常感谢。

+0

为什么你需要返回一个数据框,如果你只是在最后连接它们?在你的问题中没有什么解释为什么这个“要求”是相关的。事实上,如果您正在考虑行而不是列,那么您可能无效地处理数据。 – Alexander

+0

...你试过'pd.DataFrame.apply'方法吗?它似乎*完全*你想要的。 –

+0

@亚历山大我其实确实需要这个要求。 考虑这个炮制的例子:数据表中的每一行都是一个人的名字。要应用于每行的函数将采用该名称,并且通过任何逻辑(引用外部对象/数据帧)将返回与该名称关联的5个数字特征。现在我非常需要这个名称和它的5个特征,以DataFrame格式,即5行,2列:名称|特征 对于所有行也是如此。 –

回答

0

假设你正在申请的每一行的功能被称为f

pd.concat({i: f(row) for i, row in df.iterrows()}) 

工作实例

df = pd.DataFrame(np.arange(25).reshape(5, 5), columns=list('ABCDE')) 

def f(row): 
    return pd.concat([row] * 2, keys=['x', 'y']).unstack().drop('C', 1).assign(S=99) 

pd.concat({i: f(row) for i, row in df.iterrows()}) 

     A B D E S 
0 x 0 1 3 4 99 
    y 0 1 3 4 99 
1 x 5 6 8 9 99 
    y 5 6 8 9 99 
2 x 10 11 13 14 99 
    y 10 11 13 14 99 
3 x 15 16 18 19 99 
    y 15 16 18 19 99 
4 x 20 21 23 24 99 
    y 20 21 23 24 99 

或者

df.groupby(level=0).apply(lambda x: f(x.squeeze())) 


     A B D E S 
0 x 0 1 3 4 99 
    y 0 1 3 4 99 
1 x 5 6 8 9 99 
    y 5 6 8 9 99 
2 x 10 11 13 14 99 
    y 10 11 13 14 99 
3 x 15 16 18 19 99 
    y 15 16 18 19 99 
4 x 20 21 23 24 99 
    y 20 21 23 24 99 
0

我会做这种方式 - 虽然我注意到.apply可能是你正在寻找的东西。

import pandas as pd 
import numpy as np 

np.random.seed(7) 

orig=pd.DataFrame(np.random.rand(6,3)) 

orig.columns=(['F1','F2','F3']) 

res=[] 


for i,r in orig.iterrows(): 
    tot=0 
    for col in r: 
     tot=tot+col 
    rv={'res':tot} 
    a=pd.DataFrame.from_dict(rv,orient='index',dtype=np.float64) 
    res.append(a) 


res[0].head() 

应该返回像这样

{'res':10} 
0

目前还不清楚你想达到什么样的,但我怀疑你需要创建单独的dataframes。

下面的示例显示了如何获取数据框,将其子集合到您感兴趣的列,将函数foo应用于其中一列,然后应用返回多个值的第二个函数bar

df = pd.DataFrame({ 
    'first_name': ['john', 'nancy', 'jolly'], 
    'last_name': ['smith', 'drew', 'rogers'], 
    'A': [1, 4, 7], 
    'B': [2, 5, 8], 
    'C': [3, 6, 9] 
}) 

>>> df 
first_name last_name A B C 
0 john smith 1 2 3 
1 nancy drew 4 5 6 
2 jolly rogers 7 8 9 

def foo(first_name): 
    return 2 if first_name.startswith('j') else 1 

def bar(first_name): 
    return (2, 0) if first_name.startswith('j') else (1, 3) 

columns_of_interest = ['first_name', 'A'] 

df_new = pd.concat([ 
    df[columns_of_interest].assign(x=df.first_name.apply(foo)), 
    df.first_name.apply(bar).apply(pd.Series)], axis=1) 

>>> df_new 
first_name A x 0 1 
0 john 1 2 2 0 
1 nancy 4 1 1 3 
2 jolly 7 2 2 0 
相关问题