[英]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
如果需要返回缺少值的標量,另一個想法是使用next
和iter
:
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.