如何基于Series映射的运算符逐元合并两个同结构DataFrame?
问题描述
现有两个满足以下条件的DataFrame:df_a与df_b索引相同、列名相同、数据类型均为float;另有一个pd.Series op,满足:
op.index == df_a.indexop的每个元素为接收两个float参数并返回bool值的运算符,形式为operator(a: float, b: float) -> bool
需要实现类似df_a <op> df_b的逻辑:对df_a和df_b的每个对应单元格,使用op中对应行的运算符进行比较,得到与原DataFrame形状一致的布尔结果DataFrame。
最小示例与实现代码
初始化数据
from operator import gt, lt import pandas as pd import numpy as np df_a = pd.DataFrame({ 'CAT': {'marketCapTTM': 33.39465142383641, 'shareholdersEquityPerShareTTM': 81.05974830429687, 'tangibleBookValuePerShareTTM': 5.221448839220668, 'bookValuePerShareTTM': 12.643766377289978, 'netIncomePerShareTTM': 34.43608541699433, 'dividendYieldTTM': np.nan, 'earningsYieldTTM': np.nan, 'priceToSalesRatioTTM': np.nan, 'revenuePerShareTTM': np.nan, 'ROE': 1.6988369839109645, 'enterpriseValueTTM': np.nan, 'debtToEquityTTM': 2.8755516480792895, 'freeCashFlowPerShareTTM': 11.318374596873056, 'operatingCashFlowPerShareTTM': 3.296170855785674}, 'KO': {'marketCapTTM': 16.19804346060541, 'shareholdersEquityPerShareTTM': 13.520338019619583, 'tangibleBookValuePerShareTTM': 1.4791311212081197, 'bookValuePerShareTTM': 5.3419302547561, 'netIncomePerShareTTM': 44.63557734663028, 'dividendYieldTTM': 33.504017101396435, 'earningsYieldTTM': np.nan, 'priceToSalesRatioTTM': 11.13681987256062, 'revenuePerShareTTM': 27.529850258482526, 'ROE': np.nan, 'enterpriseValueTTM': 39.04183307431106, 'debtToEquityTTM': np.nan, 'freeCashFlowPerShareTTM': np.nan, 'operatingCashFlowPerShareTTM': np.nan}, 'DIS': {'marketCapTTM': 10.350071360171354, 'shareholdersEquityPerShareTTM': 92.3074779922466, 'tangibleBookValuePerShareTTM': 2.489890153696122, 'bookValuePerShareTTM': 16.84014609959747, 'netIncomePerShareTTM': 29.892799370630662, 'dividendYieldTTM': 7.276474595382507, 'earningsYieldTTM': 38.39492540086857, 'priceToSalesRatioTTM': 4.0478509770567825, 'revenuePerShareTTM': 9.658344729379438, 'ROE': 45.11442699745053, 'enterpriseValueTTM': np.nan, 'debtToEquityTTM': np.nan, 'freeCashFlowPerShareTTM': np.nan, 'operatingCashFlowPerShareTTM': np.nan} }) df_b = pd.DataFrame({ 'CAT': {'marketCapTTM': 29.887325295389743, 'shareholdersEquityPerShareTTM': 31.83889927186704, 'tangibleBookValuePerShareTTM': 27.134180811823384, 'bookValuePerShareTTM': 10.849504294710492, 'netIncomePerShareTTM': 20.887572108177135, 'dividendYieldTTM': np.nan, 'earningsYieldTTM': np.nan, 'priceToSalesRatioTTM': np.nan, 'revenuePerShareTTM': np.nan, 'ROE': 25.230080182979187, 'enterpriseValueTTM': np.nan, 'debtToEquityTTM': 50.175058716128994, 'freeCashFlowPerShareTTM': 39.21225330073516, 'operatingCashFlowPerShareTTM': 25.26732056715597}, 'KO': {'marketCapTTM': 35.57854672737116, 'shareholdersEquityPerShareTTM': 52.098967463491945, 'tangibleBookValuePerShareTTM': 22.943564836479496, 'bookValuePerShareTTM': 7.022975757514489, 'netIncomePerShareTTM': 4.90371517588241, 'dividendYieldTTM': 2.1442957674601324, 'earningsYieldTTM': np.nan, 'priceToSalesRatioTTM': 64.68716099305611, 'revenuePerShareTTM': 9.960264176165484, 'ROE': np.nan, 'enterpriseValueTTM': 11.32154660489711, 'debtToEquityTTM': np.nan, 'freeCashFlowPerShareTTM': np.nan, 'operatingCashFlowPerShareTTM': np.nan}, 'DIS': {'marketCapTTM': 5.935286159527827, 'shareholdersEquityPerShareTTM': 17.255701701169624, 'tangibleBookValuePerShareTTM': 37.50072163718486, 'bookValuePerShareTTM': 14.009615847232455, 'netIncomePerShareTTM': 17.91946520859328, 'dividendYieldTTM': 2.2431492946899283, 'earningsYieldTTM': 47.90549865927282, 'priceToSalesRatioTTM': 38.315078361282225, 'revenuePerShareTTM': 1.7762807962951885, 'ROE': 44.23368129207099, 'enterpriseValueTTM': np.nan, 'debtToEquityTTM': np.nan, 'freeCashFlowPerShareTTM': np.nan, 'operatingCashFlowPerShareTTM': np.nan} }) op = pd.Series({ 'marketCapTTM': gt, 'shareholdersEquityPerShareTTM': gt, 'tangibleBookValuePerShareTTM': gt, 'bookValuePerShareTTM': gt, 'netIncomePerShareTTM': gt, 'dividendYieldTTM': gt, 'earningsYieldTTM': gt, 'priceToSalesRatioTTM': gt, 'revenuePerShareTTM': gt, 'ROE': gt, 'enterpriseValueTTM': gt, 'debtToEquityTTM': gt, 'freeCashFlowPerShareTTM': gt, 'operatingCashFlowPerShareTTM': gt })
核心实现逻辑
通过apply逐行处理op,对每行对应的df_a和df_b的行数据应用指定运算符,最后重新设置索引得到结果:
# 执行运算生成结果 signals = op.reset_index().apply( lambda row: row[0](df_a.loc[row['indicator']], df_b.loc[row['indicator']]), axis=1 ).set_index(op.index) # 查看结果 print(signals)
输出结果
CAT KO DIS indicator marketCapTTM True False True shareholdersEquityPerShareTTM True False True tangibleBookValuePerShareTTM False False False bookValuePerShareTTM True False True netIncomePerShareTTM True True True dividendYieldTTM True True True earningsYieldTTM False False False priceToSalesRatioTTM False False False revenuePerShareTTM True True True ROE False True True enterpriseValueTTM True True False debtToEquityTTM False True False freeCashFlowPerShareTTM False True False operatingCashFlowPerShareTTM False True False
内容的提问来源于stack exchange,提问作者Pratik K.
相关产品推荐
相关产品推荐

