python - 如何在 groupby 之后合并列并选择 pandas 数据框中其他列的第一个有效值?

标签 python pandas numpy dataframe

我有一个以下形式的 pandas 数据框:

df

    ID    col_1    col_2    col_3    Date
     1              20       40      1/1/2018
     1     10                        1/2/2018
     1     50                60      1/3/2018
     3     40       10       90      1/1/2018
     4              80       80      1/1/2018

问题是,我需要创建一个新的数据帧,其中每列的第一个有效值,但还有从“日期”派生的附加列,这些列对应于这些值在原始数据帧中匹配的时间。

换句话说:

new_df

    ID    first_col_1    Date_col_1    first_col_2    Date_col_2    first_col_3    Date_col_3
    1         10          1/2/2018          20         1/1/2018         40         1/1/2018 
    3         40          1/1/2018          10         1/1/2018         90         1/1/2018 
    4                     1/1/2018          80         1/1/2018         80         1/1/2018

据我了解,获取每个 ID 每列的第一个有效值就像这样简单

df.groupby('ID').first()

但是如何提取每列的相关“日期”信息?

最佳答案

您不需要循环,但您确实需要在分组操作之前“融化”数据框。

所以从以下开始:

from io import StringIO
import pandas
f = StringIO("""\
ID,col_1,col_2,col_3,Date
1,,20,40,1/1/2018
1,10,,,1/2/2018
1,50,,60,1/3/2018
3,40,10,90,1/1/2018
4,,80,80,1/1/2018
""")

df = pandas.read_csv(f)

然后您可以:

print(
    df.melt(id_vars=['ID', 'Date'], value_vars=['col_1', 'col_2', 'col_3'], value_name='first')
      .groupby(by=['ID', 'variable'])
      .first()
      .unstack(level='variable')
)

这给你:

              Date                     first            
variable     col_1     col_2     col_3 col_1 col_2 col_3
ID                                                      
1         1/1/2018  1/1/2018  1/1/2018  10.0  20.0  40.0
3         1/1/2018  1/1/2018  1/1/2018  40.0  10.0  90.0
4         1/1/2018  1/1/2018  1/1/2018   NaN  80.0  80.0

这些列是多级的,因此如果您愿意,我们可以对它们进行一些修饰:

def flatten_columns(df, sep='_'):
    newcols = [sep.join(_) for _ in df.columns]
    return df.set_axis(newcols, axis='columns', inplace=False)

print(
    df.melt(id_vars=['ID', 'Date'], value_vars=['col_1', 'col_2', 'col_3'], value_name='first')
      .groupby(by=['ID', 'variable'])
      .first()
      .unstack(level='variable')
      .sort_index(level='variable', axis='columns')
      .pipe(flatten_columns)
)

这为您提供了与您的示例不完全相同的列顺序,但它与我想要的非常接近。

   Date_col_1  first_col_1 Date_col_2  first_col_2 Date_col_3  first_col_3
ID                                                                        
1    1/1/2018         10.0   1/1/2018         20.0   1/1/2018         40.0
3    1/1/2018         40.0   1/1/2018         10.0   1/1/2018         90.0
4    1/1/2018          NaN   1/1/2018         80.0   1/1/2018         80.0

关于python - 如何在 groupby 之后合并列并选择 pandas 数据框中其他列的第一个有效值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53661605/

相关文章:

python - ContextManager 访问调用 with block 的 locals()

python - 如何迭代后缀列表以添加到列表中每个变量的末尾?

python - 在 Pandas 中签名时间增量到签名秒数

python - 从 Python Dataframe 返回连续第六大值

Python 设置.py

python - 在Python中将多张Excel文件按一列拆分

python - 在 Pandas 中根据多个条件过滤 DataFrame

python - 根据值分离数据

python - 二维点的最小二乘拟合不通过对称轴

python - numpy 中的特定张量积