Рассчитать статистику по фрагментам данных - PullRequest
0 голосов
/ 13 ноября 2018

У меня есть следующий фрейм данных:

df= pd.DataFrame({'A': np.random.randn(10),
                  'B': np.concatenate((np.repeat(np.nan, 4), np.array([0.7]), np.repeat(np.nan, 4), np.array([0.5]))),
                  'C': np.random.randn(10),
                  'D': np.concatenate((np.repeat(np.nan, 4), np.array([0.2]), np.repeat(np.nan, 4), np.array([0.15])))})

это выглядит примерно так:

    A           B    C           D
0   0.537109    NaN  -0.204046   NaN
1   0.744488    NaN   0.903607   NaN
2   0.640995    NaN   0.712210   NaN
3   0.212758    NaN   0.293984   NaN
4  -1.786725    0.7   0.282747   0.20
5   1.486037    NaN  -0.199659   NaN
6   0.267356    NaN   0.890397   NaN
7   0.697408    NaN  -0.771626   NaN
8   0.044247    NaN  -1.157836   NaN
9   0.345658    0.5   1.556390   0.15

Я хотел бы рассчитать некоторую статистику, например среднее значение для срезов этого кадра данных, например, я хотел бы, чтобы результат выглядел примерно так:

    MeanA   B    MeanC  D
0   2.1     0.7  1.3    0.20
1   1.4     0.5  5.6    0.15 

Другими словами, я хочу сохранить значения не-NA из столбцов B и D и вычислить среднее и другие значения A и C из значений выше / ниже значений не-NA из B и D (в данном случае , давайте включим -1,786725 в обоих случаях, аналогично для 0,282747).

ПРИМЕЧАНИЕ: значения из MeanA и MeanC составлены из-за использования np.random.randn ().

Теперь, конечно, мой настоящий фрейм данных содержит больше столбцов и больше строк, поэтому было бы неплохо обобщить это.

Ответы [ 4 ]

0 голосов
/ 13 ноября 2018

Вот довольно простой способ. Идея состоит в том, чтобы найти строки (индекс), где каждый столбец содержит значение (точки останова). Выполните итерацию по этим точкам останова и используйте эти индексы, чтобы получить подрезок кадра данных. Вычислите среднее значение для каждого столбца в этом срезе, который вернет один ряд для этого среза. Затем просто объедините эти кусочки (серии) вместе

np.random.seed(123)
# generate random data same way as in your question

# get indices of the breakpoints
idx = df[-df.isnull().any(axis=1)].index
idx = np.insert(idx, 0, 0)  # idx will be [0, 4, 9]

# calculate mean across columns for each slice of the dataframe
# this creates a list of pandas series
slices = []

for i in range(len(idx)-1):
    slices.append(df[idx[i]:idx[i+1]+1].mean())

# concat the separate series together as rows
output = pd.concat(slices, axis=1).T

# this is needed to get the correct values of the nan columns
output[['B', 'D']] = df[['B', 'D']].dropna().values

Что дает:

          A    B         C     D
0 -0.378040  0.7 -0.073018  0.20
1 -0.230593  0.5  0.817437  0.15
0 голосов
/ 13 ноября 2018

Вы можете подойти к проблеме с помощью следующих шагов:

  1. Найдите индекс, в котором вы встретите 1-е значение, отличное от Nan, с помощью следующего кода:

    index = df['B'].first_valid_index() ## Это вернет 4

  2. Теперь нарежьте df с этими значениями индекса

    subset_df = df.iloc[0:index+1:,]

  3. принять среднее значение подмножества df для всех столбцов

    upper_half_mean = subset_df .mean(axis=0)

Выполните шаги 2 и 3 для приведенной ниже части df, а затем просто выполните конкат.

0 голосов
/ 13 ноября 2018

Это должно сделать:

b_nans = df[~df.B.isnull()].index.values
cols_stats = ['A','C']
cols_nans = ['B','D']
df2 = pd.DataFrame(columns = [['mean_'+ col for col in cols] + cols_nans])

for col_stat, col_nan in zip(cols_stats, cols_nans):
    df2[col_nan] = df[~df[col_nan].isnull()][col_nan].reset_index(drop=True)
    i_prev = 0
    for k,i in enumerate(b_nans):
        df2.loc[k, 'mean_'+ col_stat] = df.loc[i_prev:i,col_stat].mean()
        i_prev = i

print(df2)

      mean_A    mean_C       B    D
0   -0.059588   0.367446    0.7 0.20
1   0.037202    0.373243    0.5 0.15
0 голосов
/ 13 ноября 2018

Один из способов сделать это - вручную работать с индексом.Получим индексы не-NaN строк, например, по

ind = np.array(df.dropna().index)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...