簡體   English   中英

應用 function 在 pandas 中返回 dataframe

[英]apply function returns a dataframe in pandas

我有兩個數據框,一個帶有 [a,b,c] 列,另一個帶有 [a,b,d] 列,如下所示:

matrix = [(222, 34, 23),
         (333, 31, 11),
         (444, 16, 21),
         (555, 32, 22),
         (666, 33, 27),
         (777, 35, 11)
         ]

# Create a DataFrame object
dfObj = pd.DataFrame(matrix, columns=list('abc'))

print(dfObj)



     a  b   c
0   222 34  23
1   333 31  11
2   444 16  21
3   555 32  22
4   666 33  27
5   777 35  11


matrix = [(222, 34, 5),
         (333, 31, 6),
         (444, 16, 7),
         (555, 32, 8),
         (666, 33, 9),
         (777, 35, 10)
         ]

# Create a DataFrame object
dfObj1 = pd.DataFrame(matrix, columns=list('abd'))

我想用 [a,b,c,d] 列構造一個新矩陣,如下所示:

def test_func(x):
    return dfObj1.d[dfObj1['a'].isin([x['a']])]
dfObj['d'] = dfObj.apply(test_func, axis = 1)

但是dfObj.apply(test_func, axis = 1)的output是一個dataframe如下圖:

    1   2   3   4   5
1   6.0 NaN NaN NaN NaN
2   NaN 7.0 NaN NaN NaN
3   NaN NaN 8.0 NaN NaN
4   NaN NaN NaN 9.0 NaN
5   NaN NaN NaN NaN 10.0

我期待以下 output - [6,7,8,9,10]

我知道有幾種方法可以實現這一目標,但我只是想找出我在這種方法中做錯了什么。

如果在 function 中返回帶有.values的 numpy 數組,並在DataFrame.apply中添加result_type='expand'參數,則這是可能的:

def test_func(x):
    return  dfObj1.loc[dfObj1['a'].isin([x['a']]), 'd'].values

dfObj['d'] = dfObj.apply(test_func, axis = 1, result_type='expand')
print(dfObj)
     a   b   c   d
0  222  34  23   5
1  333  31  11   6
2  444  16  21   7
3  555  32  22   8
4  666  33  27   9
5  777  35  11  10

如果需要返回缺少值的標量,另一個想法是使用nextiter

def test_func(x):
    return  next(iter(dfObj1.loc[dfObj1['a'].isin([x['a']]), 'd']), np.nan)

dfObj['d'] = dfObj.apply(test_func, axis = 1)

但更好/更快的是使用DataFrame.merge

dfObj= dfObj.merge(dfObj1[['a','d']], on='a', how='left')
print(dfObj)
     a   b   c   d
0  222  34  23   5
1  333  31  11   6
2  444  16  21   7
3  555  32  22   8
4  666  33  27   9
5  777  35  11  10

Series.map

dfObj['d'] = dfObj['a'].map(dfObj1.set_index('a')['d'])
print(dfObj)
     a   b   c   d
0  222  34  23   5
1  333  31  11   6
2  444  16  21   7
3  555  32  22   8
4  666  33  27   9
5  777  35  11  10

在您的 function 中,結果返回為Series ,當您為其分配索引時,索引確實很重要,例如,索引 1 將返回索引為 1 的 Series,因此它將在 position 中顯示為矩陣。 (應用結果將連接,每個輸入都有不同的索引和列,就像一個小數據框)

def test_func(x):
    return type(dfObj1.d[dfObj1['a'].isin([x['a']])])
dfObj.apply(test_func, axis = 1)
Out[48]: 
0    <class 'pandas.core.series.Series'>
1    <class 'pandas.core.series.Series'>
2    <class 'pandas.core.series.Series'>
3    <class 'pandas.core.series.Series'>
4    <class 'pandas.core.series.Series'>
5    <class 'pandas.core.series.Series'>
dtype: object

消除索引影響以解決問題

def test_func(x):
    return dfObj1.d[dfObj1['a'].isin([x['a']])].iloc[0]
dfObj.apply(test_func, axis = 1)
Out[49]: 
0     5
1     6
2     7
3     8
4     9
5    10
dtype: int64

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM