You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pandas实现指定DataFrame转换并解决空结果问题?

Pandas DataFrame 转换问题:空DataFrame原因及解决方案

问题描述

我正尝试用Pandas处理Excel表格的DataFrame转换,需求步骤如下:

  • 选取每个数据块的前4行 + 最后2行
  • 堆叠所有数据块
  • 删除最后3个未命名列
  • 选择A列和E列
  • 向下填充A列
  • 创建包含序列值(ID-01至ID-06)的新列N1
  • 创建新列N2,拼接数据块的首个值及其编号

但我写的代码返回了一个[0 rows × 56 columns]的空DataFrame,代码如下:

import pandas as pd

myFile = r"C:\Users\wasp_96b\Desktop\ExcelSheet.xlsx"

df1 = pd.read_excel(myFile, sheet_name = 'Sheet1')

df2 = (pd.wide_to_long(df1.reset_index(), 'A' ,i='index',j='value').reset_index(drop=True))

df2.ffill(axis = 0)
                       
df2.insert(2, 'N1', 'ID-' + str(range(1, 1 + len(df2))))

df2.insert(3, 'N2', len(df2)//5)

display(df2)

空DataFrame的原因

  1. pd.wide_to_long使用错误:该函数要求列名有统一前缀(如A_1、A_2),但你的原始数据列名不符合这个格式,导致转换后无匹配数据,返回空表。
  2. 未赋值链式操作:df2.ffill(axis=0)没有重新赋值给df2,Pandas大部分操作返回新对象,原对象不会被修改。
  3. 逻辑偏离需求:代码完全没按照你列出的7步转换逻辑编写,既没有处理数据块选取,也没做列筛选等核心步骤,自然得不到预期结果。

正确实现方案

以下是严格按需求步骤编写的代码:

import pandas as pd

# 读取Excel文件
myFile = r"C:\Users\wasp_96b\Desktop\ExcelSheet.xlsx"
df = pd.read_excel(myFile, sheet_name='Sheet1')

# 识别数据块:假设数据块之间以空行分隔
block_starts = df[df['A'].notna()].index.tolist()
block_ranges = []
for i in range(len(block_starts)):
    start = block_starts[i]
    end = block_starts[i+1] - 1 if i < len(block_starts)-1 else df.index[-1]
    block_ranges.append((start, end))

# 选取每个数据块的前4行 + 最后2行
selected_rows = []
for start, end in block_ranges:
    # 前4行
    selected_rows.extend(range(start, min(start+4, end+1)))
    # 最后2行(块行数≥2时生效)
    if end - start + 1 >= 2:
        selected_rows.extend(range(end-1, end+1))

# 提取选中行并重置索引
df_selected = df.loc[selected_rows].reset_index(drop=True)

# 删除最后3个未命名列
df_selected = df_selected.iloc[:, :-3]

# 选择A列和E列(若列名不是A/E,需根据实际列名调整)
df_filtered = df_selected[['A', 'E']]

# 向下填充A列
df_filtered['A'] = df_filtered['A'].ffill(axis=0)

# 创建N1列:生成ID-01至ID-xx的序列
df_filtered['N1'] = [f'ID-{str(i+1).zfill(2)}' for i in range(len(df_filtered))]

# 创建N2列:拼接数据块首个值及其编号
block_ids = []
current_block = 0
for idx in df_selected.index:
    while current_block < len(block_ranges)-1 and idx >= block_ranges[current_block+1][0]:
        current_block += 1
    block_ids.append(current_block+1)

block_first_vals = [df.loc[start, 'A'] for start, end in block_ranges]
df_filtered['N2'] = [f"{block_first_vals[bid-1]}-{bid}" for bid in block_ids]

# 查看结果
display(df_filtered)

代码说明

  • 数据块识别:通过非空的A列行定位每个数据块的起止位置,若你的数据块分隔方式不同,可调整这部分逻辑。
  • 行选取:严格按每个块取前4行+最后2行的规则提取数据。
  • 列处理:按要求删除末尾3列、筛选指定列,再填充A列空值。
  • 新列生成:N1生成带两位数字的ID序列;N2根据数据块的首个A值和块编号拼接生成。

内容的提问来源于stack exchange,提问作者Timeless

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 19:15:52