Как заполнить кадры данных панд в цикле? - PullRequest
3 голосов
/ 17 мая 2019

Я пытаюсь построить подмножество фреймов данных из большего фрейма данных, выполнив поиск строки в заголовках столбцов.

df=pd.read_csv('data.csv')
cdf = df.drop(['DateTime'], axis=1)

wells = ['N1','N2','N3','N4','N5','N6','N7','N8','N9']
for well in wells:
    wellname = well
    well = pd.DataFrame()
    well_cols = [col for col in cdf.columns if wellname in col]
    well = cdf[well_cols]

Я пытаюсь найти имя скважины в столбцах фрейма данных cdf и поместитьте столбцы, которые содержат это имя скважины в новом кадре данных с именем скважины.

Я могу построить свои новые субкадры данных, но кадры данных оказываются пустыми с размером (0, 0), а cdf - (21973, 91),

well_cols также корректно заполняется в виде списка.

Это некоторые заголовки столбцов cdf.Каждый столбец содержит 20 тыс. Строк данных.

Index(['N1_Inj_Casing_Gas_Valve', 'N1_LT_Stm_Rate', 'N1_ST_Stm_Rate',
       'N1_Inj_Casing_Gas_Flow_Rate', 'N1_LT_Stm_Valve', 'N1_ST_Stm_Valve',
       'N1_LT_Stm_Pressure', 'N1_ST_Stm_Pressure', 'N1_Bubble_Tube_Pressure',
       'N1_Inj_Casing_Gas_Pressure', 'N2_Inj_Casing_Gas_Valve',
       'N2_LT_Stm_Rate', 'N2_ST_Stm_Rate', 'N2_Inj_Casing_Gas_Flow_Rate',
       'N2_LT_Stm_Valve', 'N2_ST_Stm_Valve', 'N2_LT_Stm_Pressure',
       'N2_ST_Stm_Pressure', 'N2_Bubble_Tube_Pressure',
       'N2_Inj_Casing_Gas_Pressure', 'N3_Inj_Casing_Gas_Valve',
       'N3_LT_Stm_Rate', 'N3_ST_Stm_Rate', 'N3_Inj_Casing_Gas_Flow_Rate',
       'N3_LT_Stm_Valve', 'N3_ST_Stm_Valve', 'N3_LT_Stm_Pressure',

Я хочу создать новый фрейм данных с каждым заголовком, который содержит «хорошо» IE, новый фрейм данных для всех столбцов и данных с именем столбца, содержащим N1, еще один для N2 и т. Д.

Новые кадры данных заполняются правильно, когда внутри цикла, но исчезают, когда цикл прерывается ... немного кода, выводимого для print(well):

[27884 rows x 10 columns]
       N9_Inj_Casing_Gas_Valve  ...  N9_Inj_Casing_Gas_Pressure
0                    74.375000  ...                 2485.602364
1                    74.520833  ...                 2485.346000
2                    74.437500  ...                 2485.341091

Ответы [ 4 ]

2 голосов
/ 17 мая 2019

IIUC этого должно быть достаточно:

df=pd.read_csv('data.csv')
cdf = df.drop(['DateTime'], axis=1)

wells = ['N1','N2','N3','N4','N5','N6','N7','N8','N9']
well_dict={}
for well in wells:

    well_cols = [col for col in cdf.columns if well in col]
    well_dict[well] = cdf[well_cols]

Словари, как правило, подходят, если вы хотите что-то заполнить. Тогда в этом случае, если вы введете well_dict['N1'], вы получите свой первый кадр данных и т. Д.

1 голос
/ 18 мая 2019

Одним из способов решения этой проблемы является использование pd.MultiIndex и Groupby.

Вы можете добавить конструкцию MultiIndex, состоящую из идентификатора скважины и имени переменной. Если у вас есть df:

   N1_a  N1_b  N2_a  N2_b
1     2     2     3     4
2     7     8     9    10

Вы можете использовать df.columns.str.split('_', expand=True) для анализа идентификатора скважины, соответствующего имени переменной (т.е. a или b).

df = pd.DataFrame(df.values, columns=df.columns.str.split('_', expand=True)).sort_index(1)

Что возвращает:

  N1    N2    
   a  b  a   b
0  2  2  3   4
1  7  8  9  10

Затем вы можете транспонировать фрейм данных и groupby уровень MultiIndex 0.

grouped = df.T.groupby(level=0)

Для возврата списка нетранспонированных кадров субданных вы можете использовать:

wells = [group.T for _, group in grouped]

, где wells[0]:

  N1   
   a  b
0  2  2
1  7  8

и wells[1]:

  N2    
   a   b
0  3   4
1  9  10

Последний шаг, скорее всего, не нужен, поскольку к данным можно получить доступ из сгруппированного объекта grouped.

Все вместе:

import pandas as pd
from io import StringIO

data = """
N1_a,N1_b,N2_a,N2_b
1,2,2,3,4
2,7,8,9,10
"""

df = pd.read_csv(StringIO(data)) 

# Parse Column names to add well name to multiindex level
df = pd.DataFrame(df.values, columns=df.columns.str.split('_', expand=True)).sort_index(1)

# Group by well name
grouped = df.T.groupby(level=0)

#bulist list of sub dataframes
wells = [group.T for _, group in grouped]
1 голос
/ 17 мая 2019

Элементы массива не изменяются при итерации по нему.То есть, вот что он делает, основываясь на вашем примере:

# 1st iteration
well = 'N1' # assigned by the for loop directive
...
well = <empty DataFrame> # assigned by `well = pd.DataFrame()`
...
well = <DataFrame, subset of cdf where col has 'N1' in name> # assigned by `well = cdf[well_cols]`
# 2nd iteration
well = 'N2' # assigned by the for loop directive
...
well = <empty DataFrame> # assigned by `well = pd.DataFrame()`
...
well = <DataFrame, subset of cdf where col has 'N2' in name> # assigned by `well = cdf[well_cols]`
...

Но вы ни разу не изменили массив или не сохранили новые кадры данных (хотя последний кадр данных все равно сохранялся бы вwell в конце итерации).

IMO, кажется, что хранить кадры данных в dict будет проще в использовании:

df=pd.read_csv('data.csv')
cdf = df.drop(['DateTime'], axis=1)

wells = ['N1','N2','N3','N4','N5','N6','N7','N8','N9']
well_dfs = {}
for well in wells:
    well_cols = [col for col in cdf.columns if well in col]
    well_dfs[well] = cdf[well_cols]

Однако, если вы действительно этого хотитев списке вы можете сделать что-то вроде:

df=pd.read_csv('data.csv')
cdf = df.drop(['DateTime'], axis=1)

wells = ['N1','N2','N3','N4','N5','N6','N7','N8','N9']
for ix, well in enumerate(wells):
    well_cols = [col for col in cdf.columns if well in col]
    wells[ix] = cdf[well_cols]
0 голосов
/ 17 мая 2019

Использование contains

df[df.columns.str.contains('|'.join(wells))]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...