冰菲 发表于 6 天前

Python处理Excel表格,运行其他列,结果是对的,换单号数量列,运行结果就错乱吗,...

df=pd.pivot_table(data11,values=['实收费用','经纪费金额','单号数量'],index=['渠道来源'],columns=None,aggfunc={'单号数量':'nunique','实收费用':'sum',''经纪费金额':'sum'}).reset_index()
df
df.columns = ['渠道来源', '实收费用', '经纪费金额','单号数量']


渠道来源      实收费用      经纪费金额      单号数量
河北分公司      1380      448                      0
河南业务部      879      882                      0
山东业务部      215      6653                      0



Python处理Excel表格,需要统计实收费用和经纪费合计金额,单号数量需要统计去重复的个数,这个代码透视其他列没问题,换成单号数量就不对了,为什么?

FishC 发表于 6 天前

您好!这个问题通常是因为数据类型不匹配或列名存在空格等隐藏字符导致的。`nunique` 对数据格式比较敏感。

主要原因和解决方案如下:

问题分析:

[*]最常见的原因是“单号数量”列的数据类型不是字符串(str),而是数值或其他类型。`nunique`在处理混合类型或非字符串类型时可能出现意外结果。
[*]列名可能有不可见的空格或特殊字符(比如您例子中`‘经纪费金额’`的引号就不一致)。
[*]数据中可能存在NaN空值,影响计数。


解决步骤:

[*] 检查列名和数据:

print(data11.columns.tolist())# 查看准确的列名
print(data11[['单号数量']].head())# 查看前几行数据
print(data11['单号数量'].dtype)# 查看数据类型


[*] 统一列名为字符串并处理空格:

# 去除列名两端的空格
data11.columns = data11.columns.str.strip()
# 如果列名确实是‘经纪费金额’(带中文引号),需要改为普通引号或正确列名
# 假设正确列名是'经纪费金额',则
data11.rename(columns={'‘经纪费金额’': '经纪费金额'}, inplace=True)


[*] 确保“单号数量”列为字符串类型:

data11['单号数量'] = data11['单号数量'].astype(str)
# 或者,如果原数据是数值型又想保留数值,可以这样
# data11['单号数量'] = data11['单号数量'].fillna('').astype(str)


[*] 使用修正后的代码:

import pandas as pd

# 假设列名已修正为:'单号数量', '实收费用', '经纪费金额'
df = pd.pivot_table(data11,
                  values=['单号数量', '实收费用', '经纪费金额'],
                  index=['渠道来源'],
                  aggfunc={'单号数量': 'nunique',
                           '实收费用': 'sum',
                           '经纪费金额': 'sum'}).reset_index()

print(df)



关键点:
请务必确保传递给 `aggfunc` 字典中的列名,与 `values` 列表中的列名完全一致(包括字符和空格)。将“单号数量”转换为字符串类型,是解决此类计数问题最有效的方法。

修正后,您的数据透视表应该能正确显示每个渠道的 去重单号数量、实收费用总和 和 经纪费金额总和 了。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

冰菲 发表于 6 天前

代码没问题,运费其他列都能得出正确结果,只有换单号数量这列才结果不正确的

FishC 发表于 6 天前

冰菲 发表于 2026-01-26 10:56
代码没问题,运费其他列都能得出正确结果,只有换单号 ...

这种情况很可能是数据格式问题。虽然代码看起来一样,但“单号数量”列的数据可能与其他列不同。

主要问题和解决方案:

1. 数据类型不一致问题
“单号数量”列可能包含混合类型数据(有些是数字,有些是字符串),这会导致 `nunique` 返回意外的结果。

检查数据类型:

# 检查单号数量列的数据类型
print(f"数据类型: {data11['单号数量'].dtype}")
print(f"混合类型检查: {data11['单号数量'].apply(type).unique()}")


统一为字符串类型:

# 将单号数量列统一转换为字符串类型
data11['单号数量'] = data11['单号数量'].astype(str)
# 或者如果需要保留数值格式,可以先转换为字符串再运行透视
data11['单号数量_str'] = data11['单号数量'].astype(str)


2. 空格或特殊字符问题
“单号数量”列可能包含不可见的空格或特殊字符。

清理数据:

# 去除空格和不可见字符
data11['单号数量'] = data11['单号数量'].astype(str).str.strip()
# 去除所有空白字符
data11['单号数量'] = data11['单号数量'].str.replace(r'\s+', '', regex=True)


3. NaN或空值问题
`nunique` 默认不计入NaN值,但有时空值会影响结果。

处理空值:

# 检查空值
print(f"空值数量: {data11['单号数量'].isna().sum()}")
print(f"空字符串数量: {(data11['单号数量'] == '').sum()}")

# 将空值替换为占位符(避免影响计数)
data11['单号数量_clean'] = data11['单号数量'].fillna('MISSING')


4. 完整解决方案
使用以下完整代码处理:


import pandas as pd
import numpy as np

# 1. 创建单号数量的清理版本
data11['单号数量_clean'] = (
    data11['单号数量']
    .astype(str)          # 转为字符串
    .str.strip()          # 去除空格
    .str.replace(r'\s+', '', regex=True)# 去除所有空白
)

# 如果值为空或NaN,标记为特殊值
data11['单号数量_clean'] = data11['单号数量_clean'].replace(['', 'nan', 'NaN', 'None'], 'EMPTY_VALUE')

# 2. 使用清理后的列进行透视
df = pd.pivot_table(
    data11,
    values=['单号数量_clean', '实收费用', '经纪费金额'],
    index=['渠道来源'],# 请替换为实际的索引列
    aggfunc={
      '单号数量_clean': 'nunique',
      '实收费用': 'sum',
      '经纪费金额': 'sum'
    }
).reset_index()

# 3. 重命名列
df.columns = ['渠道来源', '单号数量', '实收费用', '经纪费金额']

print(df)


5. 快速诊断方法
运行以下代码查看问题:


# 查看每组的实际单号数量
test = data11.groupby('渠道来源')['单号数量'].apply(lambda x: list(x.unique()))
for source, values in test.items():
    print(f"渠道来源: {source}")
    print(f"去重后单号数量: {len(values)}")
    print(f"示例值: {values[:5]}")
    print("-" * 50)


关键点:问题通常出在数据清洗环节。虽然代码语法正确,但如果数据包含不一致的类型或隐藏字符,nunique 就会返回错误结果。先确保数据干净一致,再进行聚合计算。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: Python处理Excel表格,运行其他列,结果是对的,换单号数量列,运行结果就错乱吗,...