计算数据帧切片的统计信息

时间:2018-11-13 10:57:45

标签: python pandas dataframe

我有以下数据框:

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 

换句话说,我想保留B和D列的非NA值,并计算B和D的非NA值之上/之下的值的A和C的均值和其他值(在这种情况下) ,我们在两种方式中都包含-1.786725,类似地适用于0.282747)。

注意:由于使用了np.random.randn(),因此构成了MeanA和MeanC的值。

现在,我的实际数据框包含更多的列和更多的行,因此将其概括化将是很好的。

4 个答案:

答案 0 :(得分:2)

这应该做:

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

答案 1 :(得分:0)

执行此操作的一种方法是手动使用索引。 让我们获取非NaN行的索引,例如由

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

现在您知道可以手动执行操作的索引了。

答案 2 :(得分:0)

您可以按照以下步骤解决问题:

  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)

对df的以下部分执行步骤2和3,然后进行合并。

答案 3 :(得分:0)

这是一种非常简单的方法。这个想法是找到每一列都包含一个值(断点)的行(索引)。遍历那些断点,并使用这些索引来获取数据帧的子切片。计算该切片中每一列的平均值,这将为该切片返回一个序列。然后将这些切片(系列)连接在一起

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