Pandas 中的 pivot_table 默默丢失含有 NaN 的索引
在本文中,我们将介绍 Pandas 中的 pivot_table 函数在处理含有 NaN 的索引时可能会出现的一些问题。
阅读更多:Pandas 教程
背景
Pandas 是一个在 Python 中处理数据的常用库,提供了许多方便的函数和数据结构。其中,pivot_table
函数可以将数据透视成一个新的表格,方便数据分析。
假设有一个包括多个行政区和与之对应的人口数的数据表格:
| 行政区 | 男性 | 女性 |
| —– | — | — |
| 北京 | 99 | 101 |
| 上海 | 89 | 88 |
| 广州 | 78 | NaN |
其中,广州的女性人口数缺失。我们可以使用 pivot_table
函数将数据透视成以下表格:
| 性别 | 北京 | 上海 | 广州 |
| — | — | — | — |
| 男性 | 99 | 89 | 78 |
| 女性 | 101 | 88 | NaN |
但实际上,使用 pivot_table
函数时,如果含有 NaN 的索引没有被明确指定为行或列,那么这些索引将会被默默的丢失掉。
问题的重现
我们可以使用以下代码来尝试使用 pivot_table
函数来透视上述数据:
import pandas as pd
data = pd.DataFrame({
'区域': ['北京', '北京', '上海', '上海', '广州', '广州'],
'性别': ['男性', '女性', '男性', '女性', '男性', '女性'],
'人口数': [99, 101, 89, 88, 78, pd.np.nan]
})
pivot_data = pd.pivot_table(
data,
index='性别',
columns='区域',
values='人口数'
)
print(pivot_data)
输出结果为:
区域 上海 北京 广州
性别
女性 88.0 101.0 NaN
男性 89.0 99.0 78.0
我们可以看到,广州的女性人口数被视为不存在,而没有被包括在输出中。
解决方案
为了解决这个问题,我们可以显式的告诉 pivot_table
函数如何处理含有 NaN 的索引。例如,我们可以将缺失的女性人口数视为 0,然后再使用 pivot_table
函数:
import pandas as pd
data = pd.DataFrame({
'区域': ['北京', '北京', '上海', '上海', '广州', '广州'],
'性别': ['男性', '女性', '男性', '女性', '男性', '女性'],
'人口数': [99, 101, 89, 88, 78, pd.np.nan]
})
data['人口数'] = data['人口数'].fillna(0)
pivot_data = pd.pivot_table(
data,
index='性别',
columns='区域',
values='人口数'
)
print(pivot_data)
输出结果为:
区域 上海 北京 广州
性别
女性 88.0 101.0 0.0
男性 89.0 99.0 78.0
我们可以看到,缺失的女性人口数被视为 0,正确的被包括在了输出中。
另外,我们也可以将缺失的女性人口数另外作为一列输出。我们可以使用 fillna
函数将 NaN 值填充为特定的标记(例如 未知
),然后再使用 pivot_table
函数:
import pandasimport pandas as pd
data = pd.DataFrame({
'区域': ['北京', '北京', '上海', '上海', '广州', '广州'],
'性别': ['男性', '女性', '男性', '女性', '男性', '女性'],
'人口数': [99, 101, 89, 88, 78, pd.np.nan]
})
data['人口数'] = data['人口数'].fillna('未知')
pivot_data = pd.pivot_table(
data,
index='性别',
columns='区域',
values='人口数'
)
print(pivot_data)
输出结果为:
区域 上海 北京 广州
性别
女性 88.0 101.0 未知
男性 89.0 99.0 78.0
我们可以看到,缺失的女性人口数被填充为了 '未知'
,并另外作为一列被输出了。这种方法可以使得我们在处理数据时更加灵活。
总结
在使用 Pandas 的 pivot_table
函数时,含有 NaN 的索引可能会被默默丢失。为了避免这个问题,我们可以显式的告诉函数如何处理这些索引,例如将它们视为 0 或者另外输出。这样可以使得我们的数据处理更加准确和灵活。