簡體   English   中英

如何將python函數應用於從頭開始拆分的pandas子數據框並獲取新的數據框?

[英]How to apply a python function to splitted 'from the end' pandas sub-dataframes and get a new dataframe?

問題

, in the most efficient way (may be vectorized?). 從由dim_df行構成的熊貓數據幀df開始,我需要一個新的數據幀df_new ,方法是將函數應用於尺寸為dim_blk 每個子數據幀 dim_blk 最有效的方式 )。

在下面的示例中,數據框由幾行組成,但是實際數據框將由數百萬行組成,這就是為什么我需要一個有效的解決方案的原因。

dim_df = 7 # dimension of the starting dataframe
dim_blk = 3 # number of rows of the splitted block

df = pd.DataFrame(np.arange(1,dim_df+1), columns=['TEST'])
print(df)

輸出:

   TEST
0     1
1     2
2     3
3     4
4     5
5     6
6     7

我想要的分割塊:

1     # note: this is the first block composed by a <= dim_blk number of rows
2,3,4
5,6,7 # note: this is the last block and it has dim_blk number of rows




): 我這樣做了( ):

 lst = np.arange(dim_df, 0, -dim_blk) # [7 4 1] lst_mod = lst[1:] # [4 1] to cut off the last empty sub-dataframe split_df = np.array_split(df, lst_mod[::-1]) # splitted by reversed list print(split_df) 

輸出:

 split_df: [ TEST 0 1, TEST 1 2 2 3 3 4, TEST 4 5 5 6 6 7] 

例如:

 print(split_df[1]) 

輸出:

  TEST 1 2 2 3 3 4 




我如何獲得一個新的數據幀df_new ,其中每一行都是由兩列組成的,每列分別 為每個塊的 minmax僅作為示例

即:

 # df_new Min Max 0 1 1 1 2 4 2 5 7 



謝謝,
吉爾伯托

您可以將split_df轉換為數據幀,然后使用minmax函數創建數據幀,即

split_df = pd.DataFrame(np.array_split(df['TEST'], lst_mod[::-1])) 

df_new = pd.DataFrame({"MIN":split_df.min(axis=1),"MAX":split_df.max(axis=1)}).reset_index(drop=True)

輸出:

MAX  MIN
0  1.0  1.0
1  4.0  2.0
2  7.0  5.0

解決方案從問題移到答案:

解決方案

我從側面考慮,找到了一個非常快速的解決方案:

  1. 將滾動功能應用於整個數據框
  2. 從末尾開始選擇每個num_blk

代碼(具有不同的值):

 import numpy as np import pandas as pd import time dim_df = 500000 dim_blk = 240 df = pd.DataFrame(np.arange(1,dim_df+1), columns=['TEST']) start_time = time.time() df['MAX'] = df['TEST'].rolling(dim_blk).max() df['MIN'] = df['TEST'].rolling(dim_blk).min() df[['MAX', 'MIN']] = df[['MAX', 'MIN']].fillna(method='bfill') df_split = pd.DataFrame(columns=['MIN', 'MAX']) df_split['MAX'] = df['MAX'][-1::-dim_blk][::-1] df_split['MIN'] = df['MIN'][-1::-dim_blk][::-1] df_split.reset_index(inplace=True) del(df_split['index']) print(df_split.tail()) print('\\n\\nEND\\n\\n') print("--- %s seconds ---" % (time.time() - start_time)) 

時間統計

原始代碼在545秒后停止。 新代碼在0.16秒后停止。 太棒了!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM