使用一个 Dataframe 中的最后一个有效数据索引来选择另一个 Dataframe 中的数据

我想找到第一个数据帧的最后一个有效索引,并用它来索引第二个数据帧。

所以,假设我有以下数据框(df1):


            Site 1  Site 2  Site 3  Site 4  Site 5  Site 6

Date                                                      

2000-01-01    13.0    28.0    76.0      45    90.0    58.0

2001-01-01    77.0    75.0    57.0       3    41.0    24.0

2002-01-01    50.0    29.0     2.0      65    48.0    21.0

2003-01-01     7.0    48.0    14.0      63    12.0    66.0

2004-01-01    11.0    90.0    11.0       5    47.0     6.0

2005-01-01    50.0     4.0    31.0       1    40.0    79.0

2006-01-01    30.0    98.0    91.0      96    43.0    39.0

2007-01-01    50.0    20.0    54.0      65     NaN    47.0

2008-01-01    24.0    84.0    52.0      84     NaN    81.0

2009-01-01    56.0    61.0    57.0      25     NaN    36.0

2010-01-01    87.0    45.0    68.0      65     NaN    71.0

2011-01-01    22.0    50.0    92.0      91     NaN    48.0

2012-01-01    12.0    44.0    79.0      77     NaN    25.0

2013-01-01     1.0    22.0    34.0      57     NaN    25.0

2014-01-01    94.0     NaN    86.0      97     NaN    91.0

2015-01-01     2.0     NaN    98.0      44     NaN    79.0

2016-01-01    81.0     NaN    35.0      87     NaN    32.0

2017-01-01    59.0     NaN    95.0      32     NaN    58.0

2018-01-01     NaN     NaN     3.0      14     NaN     NaN

2019-01-01     NaN     NaN    48.0       9     NaN     NaN

2020-01-01     NaN     NaN     NaN      49     NaN     NaN

现在我可以使用“first_valid_index()”找到每列的最后一个有效索引:


lvi = df.apply(lambda series: series.last_valid_index())

哪个产量:


Site 1   2017-01-01

Site 2   2013-01-01

Site 3   2019-01-01

Site 4   2020-01-01

Site 5   2006-01-01

Site 6   2017-01-01

我如何将它应用到另一个 Dataframe,我使用这个索引来切片另一个 Dataframe 的时间序列。Dataframe 的另一个示例可以使用以下方法创建:


import pandas as pd

import numpy as np

from numpy import random


random.seed(30)

idx = pd.date_range(start='2000-01-01', end='2020-01-01',freq ='AS')

df2 = df2.set_index(idx)

我如何使用那个“lvi”变量来索引 df2?


要手动执行此操作,我可以使用:


df_s1 = df['Site 1'].loc['2000-01-01':'2017-01-01']

有没有更好的方法来解决这个问题?另外,每一列本质上都必须是自己的数据框才能工作吗?任何帮助是极大的赞赏!


哔哔one
浏览 152回答 3
3回答

largeQ

这可能有点惯用:df2[df.notna()]甚至df2.where(df.notna())请注意,在这些情况下(和df1*0 + df2),操作是为了匹配df和的索引值而完成的df2。例如,df2[df.reset_index(drop=True).notna()]将返回所有nan,因为没有公共索引值。

温温酱

这似乎工作得很好:In [34]: dOut[34]:       x    yDate                2020-01-01  1.0  2.02020-01-02  1.0  2.02020-01-03  1.0  2.02020-01-04  1.0  2.02020-01-05  1.0  2.02020-01-06  1.0  NaN2020-01-07  1.0  NaN2020-01-08  1.0  NaN2020-01-09  1.0  NaN2020-01-10  1.0  NaN2020-01-11  NaN  NaN2020-01-12  NaN  NaN2020-01-13  NaN  NaN2020-01-14  NaN  NaN2020-01-15  NaN  NaN2020-01-16  NaN  NaN2020-01-17  NaN  NaN2020-01-18  NaN  NaN2020-01-19  NaN  NaN2020-01-20  NaN  NaNIn [35]: d.apply(lambda col: col.last_valid_index())Out[35]: x   2020-01-10y   2020-01-05dtype: datetime64[ns]进而: In [15]: d.apply(lambda col: col.last_valid_index()).apply(lambda date: df2.loc[date])                                                                   Out[15]:  z x  0.940396 y  0.564007

精慕HU

好吧,所以在考虑了一段时间并尝试想出一个涉及 for 循环等的详细过程之后,我得出的结论是这个简单的数学运算就可以解决问题。基本上,我利用了 pandas 中 Dataframes 之间的数学计算方式。output = df1*0 + df2这给出了 df2 的输出,它将采用 df1 的 NaN 值,如下所示:              Site 1    Site 2    Site 3    Site 4    Site 5    Site 6Date                                                                  2000-01-01  0.690597  0.443933  0.787931  0.659639  0.363606  0.9223732001-01-01  0.388669  0.577734  0.450225  0.021592  0.554249  0.3055462002-01-01  0.578212  0.927848  0.361426  0.840541  0.626881  0.5454912003-01-01  0.431668  0.128282  0.893351  0.783488  0.122182  0.6661942004-01-01  0.151491  0.928584  0.834474  0.945401  0.590830  0.8026482005-01-01  0.113477  0.398326  0.649955  0.202538  0.485927  0.1279252006-01-01  0.521906  0.458672  0.923632  0.948696  0.638754  0.5527532007-01-01  0.266599  0.839047  0.099069  0.000928       NaN  0.0181462008-01-01  0.819810  0.809779  0.706223  0.247780       NaN  0.7596912009-01-01  0.441574  0.020291  0.702551  0.468862       NaN  0.3411912010-01-01  0.277030  0.130573  0.906697  0.589474       NaN  0.8199862011-01-01  0.795344  0.103121  0.846405  0.589916       NaN  0.5644112012-01-01  0.697255  0.599767  0.206482  0.718980       NaN  0.7313662013-01-01  0.891771  0.001944  0.703132  0.751986       NaN  0.8459332014-01-01  0.672579       NaN  0.466981  0.466770       NaN  0.6180692015-01-01  0.767219       NaN  0.702156  0.370905       NaN  0.4819712016-01-01  0.315264       NaN  0.793531  0.754920       NaN  0.0914322017-01-01  0.431651       NaN  0.974520  0.708074       NaN  0.8700772018-01-01       NaN       NaN  0.408743  0.430576       NaN       NaN2019-01-01       NaN       NaN  0.751509  0.755521       NaN       NaN2020-01-01       NaN       NaN       NaN  0.518533       NaN       NaN我基本上是想将 NaN 值从一个 Dataframe 印到另一个 Dataframe 上。我不敢相信我做这件事有多困难。只要我的 Dataframes 大小相同,这就可以很好地满足我的需求。现在我应该能够从这里开始计算每个最后有效数据点的百分比变化。谢谢大家的投入!编辑:只是为了向大家展示我最终想要完成的事情,这是我在大家的帮助和建议下制作的最终代码!原来的 df 最初看起来像:            Site 1  Site 2  Site 3  Site 4  Site 5  Site 6Date                                                      2000-01-01    13.0    28.0    76.0      45    90.0    58.02001-01-01    77.0    75.0    57.0       3    41.0    24.02002-01-01    50.0    29.0     2.0      65    48.0    21.02003-01-01     7.0    48.0    14.0      63    12.0    66.02004-01-01    11.0    90.0    11.0       5    47.0     6.02005-01-01    50.0     4.0    31.0       1    40.0    79.02006-01-01    30.0    98.0    91.0      96    43.0    39.02007-01-01    50.0    20.0    54.0      65     NaN    47.02008-01-01    24.0    84.0    52.0      84     NaN    81.02009-01-01    56.0    61.0    57.0      25     NaN    36.02010-01-01    87.0    45.0    68.0      65     NaN    71.02011-01-01    22.0    50.0    92.0      91     NaN    48.02012-01-01    12.0    44.0    79.0      77     NaN    25.02013-01-01     1.0    22.0    34.0      57     NaN    25.02014-01-01    94.0     NaN    86.0      97     NaN    91.02015-01-01     2.0     NaN    98.0      44     NaN    79.02016-01-01    81.0     NaN    35.0      87     NaN    32.02017-01-01    59.0     NaN    95.0      32     NaN    58.02018-01-01     NaN     NaN     3.0      14     NaN     NaN2019-01-01     NaN     NaN    48.0       9     NaN     NaN2020-01-01     NaN     NaN     NaN      49     NaN     NaN然后我想出了第二个完整的数据框(df2):df2 = pd.DataFrame({    "Site 1": np.random.rand(21),    "Site 2": np.random.rand(21),    "Site 3": np.random.rand(21),    "Site 4": np.random.rand(21),    "Site 5": np.random.rand(21),    "Site 6": np.random.rand(21)})idx = pd.date_range(start='2000-01-01', end='2020-01-01',freq ='AS')df2 = df2.set_index(idx)现在,我将 df2 中的 nan 值替换为 df 中的 nan 值:dfr = df2[df.notna()]然后我反转数据框:dfr = dfr[::-1]valid_first = dfr.apply(lambda col: col.first_valid_index())valid_last = dfr.apply(lambda col: col.last_valid_index())现在我想要计算从最后一个有效数据点开始的百分比变化,每个列都是固定的。这给了我从现在到过去的百分比变化,相对于最近(或最后有效)的数据点。new = []for j in dfr:    m = dfr[j].loc[valid_first[j]:valid_last[j]]    pc = m / m.iloc[0]-1    new.append(pc)final = pd.concat(new,axis=1)    print(final) 这给了我:              Site 1    Site 2    Site 3    Site 4     Site 5    Site 62000-01-01  0.270209 -0.728445 -0.636105  0.380330  41.339081 -0.4621472001-01-01  0.854952 -0.827804 -0.703568 -0.787391  40.588791 -0.8848062002-01-01 -0.677757 -0.120482 -0.208255 -0.982097  54.348094 -0.4834152003-01-01 -0.322010 -0.061277 -0.382602  1.025088   5.440808 -0.6026612004-01-01  1.574451 -0.768251 -0.543260  1.210434  50.494788 -0.8593312005-01-01 -0.412226 -0.866441 -0.055027 -0.168267   1.346869 -0.3850802006-01-01  1.280867 -0.640899  0.354513  1.086703   0.000000  0.1085042007-01-01  1.121585 -0.741675 -0.735990 -0.768578        NaN -0.1194362008-01-01 -0.210467 -0.376884 -0.575106 -0.779147        NaN  0.0559492009-01-01  1.864107 -0.966827  0.566590  1.003121        NaN -0.2144822010-01-01  0.571762 -0.311459 -0.518113  1.036950        NaN -0.5139112011-01-01 -0.122525 -0.178137 -0.641642  0.197481        NaN  0.0331412012-01-01  0.403578 -0.829402  0.161753 -0.438578        NaN -0.9965952013-01-01  0.383481  0.000000 -0.305824  0.602079        NaN -0.0577112014-01-01 -0.699708       NaN -0.515074 -0.277157        NaN -0.8408732015-01-01  0.422364       NaN -0.759708  1.230037        NaN -0.6632532016-01-01 -0.418945       NaN  0.197396 -0.445260        NaN -0.2997412017-01-01  0.000000       NaN -0.897428  0.669791        NaN  0.0000002018-01-01       NaN       NaN  0.138997  0.486961        NaN       NaN2019-01-01       NaN       NaN  0.000000  0.200771        NaN       NaN2020-01-01       NaN       NaN       NaN  0.000000        NaN       NaN 我知道很多时候这些问题没有上下文,所以这里是由于您的输入而获得的最终输出。再次感谢大家的帮助!
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python