Pandas按港口筛选后转置DataFrame,将货运类型转为列、日期设为索引
解决方案
你可以通过melt + pivot的组合逻辑实现需求,代码如下:
import pandas as pd import io # 原始数据读取 df_s = """freight_type; port; 2020-01-01; 2020-01-02; 2020-01-03; 2020-01-04; 2020-01-05 rail; qd; 51204; 1024151; 100510; 715011; 1004151 vessel; qd; 81294; 1024151; 100510; 715011; 1004151 truck; qd; 59434; 756151; 100510; 715011; 1004151 rail; ts; 199952; 521151; 100510; 715011; 1004151 vessel; ts; 515254; 224151; 100510; 715011; 1004151 truck; ts; 512552; 104151; 100510; 715011; 1004151 """ df = pd.read_csv(io.StringIO(df_s), sep="; ", engine='python') # 1. 筛选指定港口数据,这里以qd港口为例 port_df = df[df['port'] == 'qd'].copy() # 2. 先把宽表的日期列转为长表格式 port_df_long = port_df.melt(id_vars=['freight_type', 'port'], var_name='date', value_name='exp') # 3. 透视表将货运类型转为列,日期设为索引 port_qd_df = port_df_long.pivot(index='date', columns='freight_type', values='exp') # 4. 重命名列名满足要求 port_qd_df.columns = [f"{col}_exp" for col in port_qd_df.columns] # 可选:重置索引把date从索引变成普通列 port_qd_df = port_qd_df.reset_index()
执行后port_qd_df输出如下:
| date | rail_exp | vessel_exp | truck_exp |
|---|---|---|---|
| 2020-01-01 | 51204 | 81294 | 59434 |
| 2020-01-02 | 1024151 | 1024151 | 756151 |
| 2020-01-03 | 100510 | 100510 | 100510 |
| 2020-01-04 | 715011 | 715011 | 715011 |
| 2020-01-05 | 1004151 | 1004151 | 1004151 |
注:你给出的预期示例中日期全部重复为2020-01-01属于笔误,实际输出会按真实日期区分。
可选:用wide_to_long实现
如果你想用pd.wide_to_long实现,代码如下:
port_df = df[df['port'] == 'qd'].copy() # 先把日期列统一加前缀方便wide_to_long识别 port_df = port_df.rename(columns={col:f"exp_{col}" for col in port_df.columns if '-' in col}) port_df_long = pd.wide_to_long(port_df, stubnames='exp', i=['port', 'freight_type'], j='date', sep='_').reset_index() port_qd_df = port_df_long.pivot(index='date', columns='freight_type', values='exp').add_suffix('_exp').reset_index()
效果和前面的方法完全一致。
内容的提问来源于stack exchange,提问作者cmp
相关产品推荐
相关产品推荐

