Как разделить информационный фрейм панд, используя столбец периодических значений - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть фрейм данных для панд, который выглядит примерно так:

v1  v2  v3  result
0  12  31  31       0
1  34  52   4       1
2  32   4   5       1
3   7  89   2       0
4   5  17   8       1
5  11  25  23       1
6   2  32  34       1
7   0   1   3       0

Как вы, наверное, заметили, в самом последнем столбце он имеет структуру из нулей и единиц.Можно ли разбить этот фрейм данных на два фрейма данных?

Мой желаемый результат будет:

df1:

v1  v2  v3  result
0  34  52   4       1
1  32   4   5       1

df2:

0   5  17   8       1
1  11  25  23       1
2   2  32  34       1

df.groupby() определенно не будет работать, поскольку он просто создаст два больших кадра данных;один с единицами, второй с нулями.Я не заинтересован в сохранении данных, помеченных как нули.

Заранее спасибо!

PS.На самом деле этот фрейм данных намного больше, поэтому я пытаюсь создать df1, df2, ... dfn

Ответы [ 3 ]

0 голосов
/ 12 сентября 2018
# Flag the rows that will be the beginning of a new dataframe
df['_start_new_gp'] = (df.result == 1) & (df.result.shift() == 0)

# Get rigs of the results = 0 (here creating a copy - not necessary)
df2 = df[df.result == 1].copy()

# Use a cumulative sum on the '_start_new_gp' column to create a "group number"
df2['_group_number'] = df2['_start_new_gp'].cumsum()

# Group by "group number"
grouped = df2.groupby('_group_number')

# Get list of dataframes
dataframes = [group for _, group in grouped]
0 голосов
/ 12 сентября 2018

Использование numpy.split:

s = df.loc[df.result.eq(1)]
idx = np.where(np.diff(s.index)!=1)[0] + 1

for d in np.split(s, idx):
    print(d, end='\n\n')

   v1  v2  v3  result
1  34  52   4       1
2  32   4   5       1

   v1  v2  v3  result
4   5  17   8       1
5  11  25  23       1
6   2  32  34       1
0 голосов
/ 12 сентября 2018

Вы можете создать dictionary of DataFrames:

mask = df['result'].eq(1)
a = pd.factorize(df['result'].eq(0).cumsum()[mask])[0]
dfs = dict(tuple(df[mask].groupby(a)))
print (dfs[0])
   v1  v2  v3  result
1  34  52   4       1
2  32   4   5       1

print (dfs[1])
   v1  v2  v3  result
4   5  17   8       1
5  11  25  23       1
6   2  32  34       1

Подробно :

Создать логическую маску для фильтрации по eq (==):

mask = df['result'].eq(1)
print (mask)
0    False
1     True
2     True
3    False
4     True
5     True
6     True
7    False
Name: result, dtype: bool

Создать счетчик Series путем сравнения по 0 и Series.cumsum:

print (df['result'].eq(0).cumsum())
0    1
1    1
2    1
3    2
4    2
5    2
6    2
7    3
Name: result, dtype: int32

Фильтрация по boolean indexing только 1 строк:

print (df['result'].eq(0).cumsum()[mask])
1    1
2    1
4    2
5    2
6    2
Name: result, dtype: int32

Добавить factorize для групп, сортируемых по 0:

a  = pd.factorize(df['result'].eq(0).cumsum()[mask])[0]
print (a)
[0 0 1 1 1]

Создать словарь изgroupby объект, но также фильтровать строки по логической маске:

dfs = dict(tuple(df[mask].groupby(a)))
print (dfs)
{0:    v1  v2  v3  result
1  34  52   4       1
2  32   4   5       1, 1:    v1  v2  v3  result
4   5  17   8       1
5  11  25  23       1
6   2  32  34       1}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...