为什么 pandas 在 2 列数据帧上的数据透视表计数与 aggfunc=len 一起工作,但结果是计数为空的数据集?

问题描述 投票:0回答:1

为什么我不能用

len
替换下面的
"count"
并保持相同的输出行为?。我的意思是,它运行没有错误,但输出是非常不同,如果我将
len
更改为
count
,我会得到一个数据集。

import pandas as pd

data = {'Category': ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C'],
        'Value': [10, 20, 30, 40, 50, 60, 70, 80, 90]}

df = pd.DataFrame(data)

pivot_table = df.pivot_table(index='Category', columns='Value', values='Value', aggfunc=len)

print(pivot_table)

结果:

Value      10   20   30   40   50   60   70   80   90
Category                                             
A         1.0  NaN  NaN  1.0  NaN  NaN  1.0  NaN  NaN
B         NaN  1.0  NaN  NaN  1.0  NaN  NaN  1.0  NaN
C         NaN  NaN  1.0  NaN  NaN  1.0  NaN  NaN  1.0

size
产生与 len:

相同的结果
pivot_table = df.pivot_table(index='Category', columns='Value', values='Value', aggfunc="size")

更奇怪的是,如果我执行这个奇怪的解决方法,我可以使“count”像“size”(或len)一样工作:使用不同的“ValueCopy”名称创建 Value 的副本:

df["ValueCopy"] = df["Value"]
pivot_table = df.pivot_table(index='Category', columns='Value', values='ValueCopy', aggfunc="count")

但是如果我将

pivot_table
调用更改为使用
"count"
而不使用额外的虚拟列解决方法:

pivot_table = df.pivot_table(index='Category', columns='Value', values='Value', aggfunc="count")

其结果是:

Empty DataFrame
Columns: []
Index: [A, B, C]

问题:

  • 我遇到了 Pandas bug 吗?
  • 这是 Pandas 的预期行为吗?
  • 如果不调用
    "count"
    len
    如何工作? (我尝试阅读pivot_table Pandas代码,但我发现它太复杂了)
  • 为什么创建值列的虚拟副本会使 count 像 size (和 len)一样工作?
  • count 在 Polars 和 DuckDb 中运行良好的事实是否表明这是 Pandas 中的缺陷? (见下文)

Polars 中,“计数”效果非常好:

import polars as pl

# Create a DataFrame
data = {
    'Category': ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C'],
    'Value': [10, 20, 30, 40, 50, 60, 70, 80, 90]
}
df = pl.DataFrame(data)

# Pivot the DataFrame
pivot_table = df.pivot(index='Category', columns='Value', values='Value', aggregate_function="count")

# Print the pivot table
print(pivot_table)

结果:

Shape: (3, 10)
┌──────────┬──────┬──────┬──────┬───┬──────┬──────┬──────┬──────┐
│ Category ┆ 10   ┆ 20   ┆ 30   ┆ … ┆ 60   ┆ 70   ┆ 80   ┆ 90   │
│ ---      ┆ ---  ┆ ---  ┆ ---  ┆   ┆ ---  ┆ ---  ┆ ---  ┆ ---  │
│ str      ┆ u32  ┆ u32  ┆ u32  ┆   ┆ u32  ┆ u32  ┆ u32  ┆ u32  │
╞══════════╪══════╪══════╪══════╪═══╪══════╪══════╪══════╪══════╡
│ A        ┆ 1    ┆ null ┆ null ┆ … ┆ null ┆ 1    ┆ null ┆ null │
│ B        ┆ null ┆ 1    ┆ null ┆ … ┆ null ┆ null ┆ 1    ┆ null │
│ C        ┆ null ┆ null ┆ 1    ┆ … ┆ 1    ┆ null ┆ null ┆ 1    │
└──────────┴──────┴──────┴──────┴───┴──────┴──────┴──────┴──────┘

同样DuckDb SQL 数据透视计数也没有问题:

import pandas as pd
import duckdb

# Your existing DataFrame
data = {'Category': ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C'],
        'Value': [10, 20, 30, 40, 50, 60, 70, 80, 90]}
df = pd.DataFrame(data)

# Create a DuckDB connection
con = duckdb.connect()

# Register the DataFrame with DuckDB
con.register('df_pivot', df)

# Perform the pivot operation in DuckDB
query = """

PIVOT df_pivot
ON Value
USING Count(Value)
GROUP BY Category

"""
pivot_table = con.execute(query).fetchdf()

print(pivot_table)

结果:

  Category  10  20  30  40  50  60  70  80  90
0        A   1   0   0   1   0   0   1   0   0
1        B   0   1   0   0   1   0   0   1   0
2        C   0   0   1   0   0   1   0   0   1
pandas count pivot-table python-polars duckdb
1个回答
0
投票

在 Pandas 中,

pivot_table
在某些时候会调用
groupby(index+columns)

在您的示例中,这意味着对仅有的两个现有列进行分组,因此没有可计数的值。

在这种情况下使用

len
时,它会返回每个组的长度作为 DataFrame(使用
DataFrame.__len__
,返回
len(self.index)
)——在我看来,这比不返回任何内容更奇怪。

© www.soinside.com 2019 - 2024. All rights reserved.