条件为真时,Pandas将数据帧拆分为多个

时间:2018-02-13 15:17:45

标签: python python-3.x pandas split

我有一个数据框,如下面的df。我想为条件为真的每个数据块创建一个新的数据帧,这样它就会返回df_1,df_2 .... df_n。

|      df           |       |  df_1 |   | df_2  |
| Value | Condition |       | Value |   | Value |
|-------|-----------|       |-------|---|-------|
| 2     | True      |   |   | 2     |   | 0     |
| 5     | True      |   |   | 5     |   | 5     |
| 4     | True      |   |   | 4     |   |       |
| 4     | False     |   |   |       |   |       |
| 2     | False     |   |   |       |   |       |
| 0     | True      |   |   |       |   |       |
| 5     | True      |   |   |       |   |       |
| 7     | False     |   |   |       |   |       |
| 8     | False     |   |   |       |   |       |      
| 9     | False     |   |   |       |   |       |

我唯一的想法是遍历数据帧,为每个True值块返回开始和结束索引,然后创建新的数据帧,循环遍历返回的索引,为每个开始/结束对返回类似的内容:< / p>

newdf = df.iloc[start:end]

但这样做似乎效率低下。

3 个答案:

答案 0 :(得分:4)

DataFrame由反向布尔列创建的Series创建NaN字典,并按cumsum添加g = (~df['Condition']).cumsum().where(df['Condition']) print (g) 0 0.0 1 0.0 2 0.0 3 NaN 4 NaN 5 2.0 6 2.0 7 NaN 8 NaN 9 NaN Name: Condition, dtype: float64 #enumerate for starting groups from 1, 2, N dfs = {i+1:v for i, (k, v) in enumerate(df[['Value']].groupby(g))} print (dfs) {1: Value 0 2 1 5 2 4, 2: Value 5 0 6 5} print (dfs[1]) Value 0 2 1 5 2 4 print (dfs[2]) Value 5 0 6 5 s为无组:

{{1}}

答案 1 :(得分:3)

这是另一种解决方案。请注意,consecutive_groups配方来自more_itertools库。

from itertools import groupby
from operator import itemgetter

def consecutive_groups(iterable, ordering=lambda x: x):
    for k, g in groupby(enumerate(iterable), key=lambda x: x[0] - ordering(x[1])):
        yield map(itemgetter(1), g)

grps = consecutive_groups(df[df.Condition].index)

dfs = {i: df.iloc[list(j)] for i, j in enumerate(grps, 1)}

# {1:    Value Condition
# 0      2      True
# 1      5      True
# 2      4      True,
# 2:    Value Condition
# 5      0      True
# 6      5      True}

答案 2 :(得分:2)

我决定提供一个答案,将每个'Value'放入自己的列中。

m = df.Condition.values
g = (~m).cumsum()
d = df.loc[m, 'Value']
g = g[m]
c = d.groupby(g).cumcount()
d.set_axis([c, g], inplace=False).unstack()

     0    2
0  2.0  0.0
1  5.0  5.0
2  4.0  NaN