【问题标题】:How to apply a python function to splitted 'from the end' pandas sub-dataframes and get a new dataframe?如何将 python 函数应用于拆分的“从末端”熊猫子数据帧并获得新的数据帧?
【发布时间】:2017-07-12 15:24:43
【问题描述】:

问题

从由 dim_df 行组成的 pandas 数据框 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,其中每一行由两列组成,min 和 max(只是一个示例) 为每个块计算?

即:

# df_new

    Min   Max
0     1     1
1     2     4
2     5     7



谢谢,
吉尔伯托

【问题讨论】:

    标签: python function pandas numpy split


    【解决方案1】:

    您可以将split_df 转换为数据框,然后使用min 和max 函数创建数据框,即

    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)
    

    输出:

    最大最小值 0 1.0 1.0 1 4.0 2.0 2 7.0 5.0

    【讨论】:

      【解决方案2】:

      从问题到答案的移动解决方案:

      解决方案

      我横向思考并找到了一个非常快速的解决方案:

      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 秒后停止。太棒了!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多