我正在寻找一个功能,实现以下。最好用一个例子来说明。考虑:

pd.DataFrame([ [1, 2, 3 ], [4, 5, np.nan ]], columns=['x', 'y1', 'y2'])

看起来像:
   x  y1   y2
0  1   2  3
1  4   5  NaN

我想对y1y2列进行collapase,在必要时延长DataFame,以便输出:
   x  y
0  1   2
1  1   3
2  4   5

也就是说,对于xy1xy2之间的每个组合,一行。我正在寻找一个相对有效的函数,因为我有多个ys和许多行。

最佳答案

这是一个基于NumPy的,因为你在寻找性能-

def gather_columns(df):
    col_mask = [i.startswith('y') for i in df.columns]
    ally_vals = df.iloc[:,col_mask].values
    y_valid_mask = ~np.isnan(ally_vals)

    reps = np.count_nonzero(y_valid_mask, axis=1)
    x_vals = np.repeat(df.x.values, reps)
    y_vals = ally_vals[y_valid_mask]
    return pd.DataFrame({'x':x_vals, 'y':y_vals})

样本运行-
In [78]: df #(added more cols for variety)
Out[78]:
   x  y1   y2   y5   y7
0  1   2  3.0  NaN  NaN
1  4   5  NaN  6.0  7.0

In [79]: gather_columns(df)
Out[79]:
   x    y
0  1  2.0
1  1  3.0
2  4  5.0
3  4  6.0
4  4  7.0

如果y列总是从第二列开始直到结束,那么我们可以简单地对数据帧进行切片,从而进一步提高性能,如下所示-
def gather_columns_v2(df):
    ally_vals = df.iloc[:,1:].values
    y_valid_mask = ~np.isnan(ally_vals)

    reps = np.count_nonzero(y_valid_mask, axis=1)
    x_vals = np.repeat(df.x.values, reps)
    y_vals = ally_vals[y_valid_mask]
    return pd.DataFrame({'x':x_vals, 'y':y_vals})

关于python - 根据Pandas中的堆栈列延长DataFrame,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50481372/

10-12 17:10