pandas 检查一个 Dataframe 的列名是否与另一个 Dataframe 的索引值匹配,并将值填充到新列中

s6fujrry  于 2022-12-16  发布在  其他
关注(0)|答案(2)|浏览(133)

我有两个 Dataframe ,df_rates和df_profit,如下所示。df_rates有一个时间-日期值,其列名的值为某些比率,索引值表示该列的时间-日期值之前的分钟数。(即,第1行表示2012-03-31 23:45:00之前的0分钟,第2行表示2012-03-31 23:45:00之前的5分钟,以此类推)。而df_profit有时间戳作为其索引,并有一个利润列。
我想在以下条件下将df_profit中的Profit列作为新列添加到df_rates中:

  1.   如果df_profit索引处的时间戳(2012-03-31 23:45:00)与df_rates列名(2012-03-31 23:45:00)匹配,则使用相应的利润值(354.664)填充新列。
  2.   df_profit的利润列中的下一个值(125.76),其中时间戳为“2012-03-31 23:30:00”,应根据“时间之前的分钟数”为15的行填充到新列中,依此类推。(由于2012-03-31 23:45:00和2012-03-31 23:30:00之间的时间差为15分钟)

我一直在尝试很多如何做,但我不知所措。有人能帮助或指导这一点吗?

df_rates
Mins before time     2012-03-31 23:45:00
0                        113.1
5                        112.1
10                       113.1
15                       113.17
20                       103.17
25                       133.17
30                       101.39

df_profit
                         Profit
2012-04-01 00:30:00      251.71
2012-04-01 00:15:00      652.782
2012-04-01 00:00:00      458.099
2012-03-31 23:45:00      3504.664
2012-03-31 23:30:00      1215.76
2012-03-31 23:15:00     -21.48
2012-03-31 23:00:00     -8.538
    

Expected dataframe:
Mins before time    2022-01-31 23:45:00+01:00   New_column
0                      113.1                     3504.664
5                      112.1    
10                     113.1    
15                     113.17                    1215.76
20                     103.17   
25                     133.17   
30                     101.39                    -21.48
pcww981p

pcww981p1#

作为原始答案的替代(见下文),这里有一个非常直接的方法来完成OP的要求:

df_rates['Profit'] = df_profit.Profit.reindex(df_rates.columns[-1] - pd.to_timedelta(df_rates['Mins before time'], unit='min')).to_numpy()

输出:

Mins before time  2012-03-31 23:45:00    Profit
0                 0               113.10  3504.664
1                 5               112.10       NaN
2                10               113.10       NaN
3                15               113.17  1215.760
4                20               103.17       NaN
5                25               133.17       NaN
6                30               101.39   -21.480

说明:

  • 通过从df_rates中最后一列的Timestamp标签(假定为Timestamp类型,否则将其 Package 在pd.to_datetime()中)中减去使用Mins before time列创建的一系列时间增量值(单位为分钟),创建一系列时间戳
  • 在df_profit上使用reindex创建一系列利润数字,这些数字与df_rates列平行,并包含df_profit中的Profit值,其中df_profit索引中的时间戳标签与上一步中创建的时间戳系列中的标签完全匹配,其他位置为NaN
  • 将该系列的利润数字(可能包括NaN)转换为to_numpy的numpy数组,并使用它初始化df_rates中标记为Profit(或任何其他所需的标记)的新列。
    原答复:

下面是一个方法:

df_rates = ( df_rates
    .set_index(df_rates.columns[-1] + pd.to_timedelta(-df_rates['Mins before time'], unit='min'))
    .join(df_profit).reset_index(drop=True) )
print(df_rates)

输出:

Mins before time  2012-03-31 23:45:00    Profit
0                 0               113.10  3504.664
1                 5               112.10       NaN
2                10               113.10       NaN
3                15               113.17  1215.760
4                20               103.17       NaN
5                25               133.17       NaN
6                30               101.39   -21.480

解释

  • 将df_rates的索引设置为其最后一列的标签(假定为时间戳类型,否则将其 Package 为pd.to_datetime())加上一系列等于Mins before time列的时间增量值(单位为分钟)
  • 使用带有df_profit的join在索引值匹配的行中添加一个具有非空值的Profit列,并重置索引。
8iwquhpp

8iwquhpp2#

您可以定义一个函数来获取相应时间戳的利润:

# import dateutil.parser
# from datetime import timedelta

def getProfit_atDelay(delayMins, startTime, profitDF):
    try: 
        startTime = dateutil.parser.parse(str(startTime))
        dTime = startTime - timedelta(minutes=int(str(delayMins)))
        return profitDF['Profit'].loc[dTime]
    except: return None

(我假设df_profit索引包含datetime数据类型;否则,请编辑代码以将dTime转换为匹配的数据类型。)
要获取新列的所有值:

def profits_for_rates(ratesDF, profitDF):
    rStart, rMins = ratesDF.columns[1], ratesDF['Mins before time']
    return [getProfit_atDelay(t, rStart, profitDF) for t in rMins]

如果你把它当作

df_rates['New_column'] = profits_for_rates(df_rates, df_profit)

那么df_rates看起来就像

Mins before time  2012-03-31 23:45:00  New_column
0                 0               113.10    3504.664
1                 5               112.10         NaN
2                10               113.10         NaN
3                15               113.17    1215.760
4                20               103.17         NaN
5                25               133.17         NaN
6                30               101.39     -21.480

相关问题