Pandas:如何基于指定列数值重复DataFrame行?求助
解决方法:根据指定列数值重复行并转换格式
没问题,我帮你搞定这个需求!你要的其实是先把宽格式的日期列转成长格式,再根据每个日期对应的数值重复行,对吧?看我给你一步步实现:
第一步:构造示例数据
先把你给出的示例DataFrame用代码还原出来:
import pandas as pd df = pd.DataFrame({ 'Company': ['google', 'google'], 'WEEK_DAYS': ['MON-FRI', 'TUE'], 'SEPTEMBER 15': [0, 3], 'SEPTEMBER 22': [0, 2], 'SEPTEMBER 29': [5, 0], 'value': [0.5, 0.7] })
第二步:把宽表转成窄表(提取日期列)
用melt方法把三个日期列转成单独的WEEK列,同时保留对应的重复次数(原日期列的数值):
# 转成长格式,拆分日期列和重复次数 melted_df = df.melt( id_vars=['Company', 'WEEK_DAYS', 'value'], # 保留不需要转换的列 value_vars=['SEPTEMBER 15', 'SEPTEMBER 22', 'SEPTEMBER 29'], # 需要转换的日期列 var_name='WEEK', # 新日期列的名称 value_name='count' # 重复次数列的名称 )
这一步后得到的melted_df会是这样的结构:
| Company | WEEK_DAYS | value | WEEK | count |
|---|---|---|---|---|
| MON-FRI | 0.5 | SEPTEMBER 15 | 0 | |
| TUE | 0.7 | SEPTEMBER 15 | 3 | |
| MON-FRI | 0.5 | SEPTEMBER 22 | 0 | |
| TUE | 0.7 | SEPTEMBER 22 | 2 | |
| MON-FRI | 0.5 | SEPTEMBER 29 | 5 | |
| TUE | 0.7 | SEPTEMBER 29 | 0 |
第三步:过滤不需要重复的行
把count为0的行过滤掉,因为这些行不需要重复:
filtered_df = melted_df[melted_df['count'] > 0]
第四步:根据count值重复每行
这里有两种简单的实现方式:
方式1:用repeat方法(兼容所有pandas版本)
# 根据count列的数值重复对应行 result_df = filtered_df.loc[filtered_df.index.repeat(filtered_df['count'])]
方式2:用explode方法(pandas 1.3.0+版本可用,更直观)
# 先创建一个和重复次数匹配的列表,再拆分列表实现行重复 result_df = filtered_df.assign( temp=lambda x: x['count'].apply(lambda n: [n]*n) ).explode('temp')
第五步:清理最终结果
去掉多余的count(或temp)列,重置索引:
result_df = result_df.drop(columns=['count']).reset_index(drop=True)
最终结果
运行完上面的代码后,你会得到完全符合预期的输出:
| Company | WEEK_DAYS | value | WEEK |
|---|---|---|---|
| MON-FRI | 0.5 | SEPTEMBER 29 | |
| MON-FRI | 0.5 | SEPTEMBER 29 | |
| MON-FRI | 0.5 | SEPTEMBER 29 | |
| MON-FRI | 0.5 | SEPTEMBER 29 | |
| MON-FRI | 0.5 | SEPTEMBER 29 | |
| TUE | 0.7 | SEPTEMBER 15 | |
| TUE | 0.7 | SEPTEMBER 15 | |
| TUE | 0.7 | SEPTEMBER 15 | |
| TUE | 0.7 | SEPTEMBER 22 | |
| TUE | 0.7 | SEPTEMBER 22 |
为什么之前的stack/pivot没成功?
stack多用于处理多层索引的宽表转长,pivot则是长表转宽表,而你的需求是先转长格式,再根据数值重复行,所以melt+repeat/explode才是更匹配的组合~
内容的提问来源于stack exchange,提问作者Binyamin Even
相关产品推荐
相关产品推荐

