Skip to main content
 首页 » 编程设计

python之如何从 Pandas 数据框中的不同点选择行

2025年05月04日23txw1958

我如何从多个点中选择/切片,在这种情况下,从所有列的 max() 开始。每只股票都有自己的最大值,因此应从该特定点开始选择。

df 
>>>                                     TSLA             MSFT 
2017-05-15 00:00:00+00:00                314              68 
2017-05-16 00:00:00+00:00                319              69 
2017-05-17 00:00:00+00:00                320              61 
2017-05-18 00:00:00+00:00                313              66 
2017-05-19 00:00:00+00:00                316              70 
2017-05-22 00:00:00+00:00                314              65 
2017-05-23 00:00:00+00:00                310              63 
 
 
max_idx = df.idxmax() # returns index of max value 
>>> TSLA    2017-05-17 00:00:00+00:00 
>>> MSFT    2017-05-19 00:00:00+00:00 
 
max_value = df.max() # returns max value 
>>> TSLA = 320 
>>> MSFT = 70 

他们有什么方式喜欢使用, df2 = df.loc[max_idx:] 我想要这样的输出,以便我以后可以在此新输出上再次找到 max_value 和 max_idx,

TSLA    2017-05-17 00:00:00+00:00   
MSFT    2017-05-19 00:00:00+00:00 

EDIT : am expecting the following output:

   df2 
>>> TSLA                                  MSFT 
    2017-05-17 00:00:00+00:00     320     2017-05-19 00:00:00+00:00   70 
    2017-05-18 00:00:00+00:00     313     2017-05-22 00:00:00+00:00   65      
    2017-05-19 00:00:00+00:00     316     2017-05-23 00:00:00+00:00   63        
    2017-05-22 00:00:00+00:00     314              
    2017-05-23 00:00:00+00:00     310 

与@Unutbu 使用多重索引的方式类似,如果可能,新数据帧可以被多重索引。

例如,我只发布了 2 个专栏,但它们将有 100 个专栏, 所以请记住这样的大数据。谢谢!

请您参考如下方法:

您可以使用apply 方法:

In [204]: df.apply(lambda s: s.loc[s.idxmax():]) 
Out[204]:  
            MSFT  TSLA 
2017-05-17   NaN   320 
2017-05-18   NaN   313 
2017-05-19  70.0   316 
2017-05-22  65.0   314 
2017-05-23  63.0   310 

或者,构建在 MaxU's answer 上,

In [205]: pd.concat({c:df.loc[max_idx[c]:, c] for c in df.columns}).unstack(level=0) 
Out[205]:  
            MSFT   TSLA 
2017-05-17   NaN  320.0 
2017-05-18   NaN  313.0 
2017-05-19  70.0  316.0 
2017-05-22  65.0  314.0 
2017-05-23  63.0  310.0 

这两种解决方案都在列上循环。 (df.apply 的循环是在 引擎盖,但它在性能方面相当于 Python 速度循环。)我知道你 正在寻找矢量化解决方案,但在这种情况下,我看不到一种方法 避免循环。


如果您想避免 NaN,您可以不堆叠答案:

In [208]: pd.concat({c:df.loc[max_idx[c]:, c] for c in df.columns}) 
Out[208]:  
MSFT  2017-05-19     70 
      2017-05-22     65 
      2017-05-23     63 
TSLA  2017-05-17    320 
      2017-05-18    313 
      2017-05-19    316 
      2017-05-22    314 
      2017-05-23    310 
dtype: int64 

或者,如果您正在使用 df.apply,请调用 stack 将列标签移动到行索引的级别:

In [213]: df.apply(lambda s: s.loc[s.idxmax():]).T.stack() 
Out[213]:  
MSFT  2017-05-19     70.0 
      2017-05-22     65.0 
      2017-05-23     63.0 
TSLA  2017-05-17    320.0 
      2017-05-18    313.0 
      2017-05-19    316.0 
      2017-05-22    314.0 
      2017-05-23    310.0 
dtype: float64 

那么让我们看看性能。使用此设置(在更大的 DataFrame 上进行测试):

shape = (1000,2000) 
bigdf = pd.DataFrame(np.random.randint(100, size=shape), 
                     index=pd.date_range('2000-1-1', periods=N)) 
 
def using_apply(df): 
    return df.apply(lambda s: s.loc[s.idxmax():]) 
 
def using_loop(df): 
    max_idx = df.idxmax() 
    return pd.concat({c:df.loc[max_idx[c]:, c] for c in df.columns}).unstack(level=0) 

MaxU 的 using_loop 比 using_apply 稍快:

In [202]: %timeit using_apply(bigdf) 
1 loop, best of 3: 1.45 s per loop 
 
In [203]: %timeit using_loop(bigdf) 
1 loop, best of 3: 1.22 s per loop 

但是注意,最好在自己的机器上测试benchmarks作为结果 可能会有所不同。