【问题标题】:Splitting pandas dataframe into many chunks将 pandas 数据框拆分为许多块
【发布时间】:2016-10-24 00:17:43
【问题描述】:

假设我有一个具有以下结构的数据框:

    observation
d1  1
d2  1
d3  -1
d4  -1
d5  -1
d6  -1
d7  1
d8  1
d9  1
d10 1
d11 -1
d12 -1
d13 -1  
d14 -1
d15 -1
d16 1
d17 1
d18 1
d19 1
d20 1

其中 d1:d20 是一些日期时间索引(此处概括)。

如果我想将 d1:d2、d3:d6、d7:d10 等拆分为各自的“块”,我将如何以 Python 方式执行此操作?

注意:

df1 = df[(df.observation==1)]
df2 = df[(df.observation==-1)]

不是我想要的。

我能想到蛮力的方法,这可行,但不是非常优雅。

【问题讨论】:

  • 你如何获得这些数据? pandas.read_csv() 有自己的 chunksize 参数
  • @StevenG 这些是分析值,这是一个简化的示例。基本上,我将拥有具有不同值的顺序数据。我想将这些不同的值组拆分为新的数据框。 chunksize 似乎也需要对传入数据结构的先验知识,而我没有。
  • 你希望它如何分块?标准是什么?您是否根据observation 的更改时间分块

标签: python pandas


【解决方案1】:

您可以根据observation 列的diff()cumsum() 创建一个组变量,如果diff() 不等于0,则分配一个True 值,因此每次出现一个新值,将使用cumsum() 创建一个新的组ID,然后您可以在groupby() 之后使用df.groupby((df.observation.diff() != 0).cumsum())...(other chained analysis here) 应用标准分析,或者使用list-comprehension 将它们拆分为更小的数据框:

lst = [g for _, g in df.groupby((df.observation.diff() != 0).cumsum())]

lst[0]
# observation
#d1         1
#d2         1

lst[1]
# observation
#d3        -1
#d4        -1
#d5        -1
#d6        -1
...

在此处索引块:

[i.index for i in lst]

#[Index(['d1', 'd2'], dtype='object'),
# Index(['d3', 'd4', 'd5', 'd6'], dtype='object'),
# Index(['d7', 'd8', 'd9', 'd10'], dtype='object'),
# Index(['d11', 'd12', 'd13', 'd14', 'd15'], dtype='object'),
# Index(['d16', 'd17', 'd18', 'd19', 'd20'], dtype='object')]

【讨论】:

    【解决方案2】:

    这是一个使用真正的 date.datetime 对象作为索引的示例。

    import pandas as pd
    import numpy as np
    import datetime
    import random
    
    df = pd.DataFrame({'x': np.random.randn(40)}, index = [date.fromordinal(random.randint(start_date, end_date)) for i in range(40)])
    
    def filter_on_datetime(df, year = None, month = None, day = None):
        if all(d is not None for d in {year, month, day}):
            idxs = [idx for idx in df.index if idx.year == year and idx.month == month and idx.day == day]
        elif year is not None and month is not None and day is None:
            idxs = [idx for idx in df.index if idx.year == year and idx.month == month]
        elif year is not None and month is None and day is None:
            idxs = [idx for idx in df.index if idx.year == year]
        elif year is None and month is not None and day is not None:
            idxs = [idx for idx in df.index if idx.month == month and idx.day == day]
        elif year is None and month is None and day is not None:
            idxs = [idx for idx in df.index if idx.day == day]
        elif year is None and month is not None and day is None:
            idxs = [idx for idx in df.index if idx.month == month]
        elif year is not None and month is None and day is not None:
            idxs = [idx for idx in df.index if idx.year == year and idx.day == day] 
        else:
            idxs = df.index
        return df.ix[idxs]
    

    运行这个:

    >>> print(filter_on_datetime(df = df, year = 2016, month = 2))
                       x
    2016-02-01 -0.141557
    2016-02-03  0.162429
    2016-02-05  0.703794
    2016-02-07 -0.184492
    2016-02-09 -0.921793
    2016-02-12  1.593838
    2016-02-17  2.784899
    2016-02-19  0.034721
    2016-02-26 -0.142299
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-24
      • 2022-08-12
      • 2021-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-17
      • 2017-08-29
      相关资源
      最近更新 更多