【问题标题】:Pandas describe() behaviour for numeric dtypes数字 dtypes 的 Pandas describe() 行为
【发布时间】:2015-09-02 08:27:22
【问题描述】:

函数 DataFrame.describe() 的输出取决于数据类型。

当用于数字 dtype 时,它​​将返回以下输出:

f.ID.describe()

count       7583.000000
mean      704013.191613
std      1192979.985253
min        10575.000000
25%        10575.000000
50%        10864.000000
75%      2084161.000000
max      6422339.000000

这在大多数情况下都有意义,除非列包含不应聚合的数字数据。例如:身份证。

在这种情况下,以下输出会更合适:

count      7583
unique       68
top       10864
freq       3390

以上是您为 object dtype 获得的输出。在 ID 的情况下,列的唯一性和大小对我来说比平均值或分布更有价值。

据我所知,对数字 dtype 执行此操作的唯一方法是首先将其转换为 object dtype,例如

f.ID.astype(str).describe()

数据类型转换可能会带来性能损失(我想对于大型数据集更明显)。这就是为什么我想知道是否有任何其他方法可以修改 describe() 行为,而不是更改数据类型(动态或创建 DataFrame 时)。

【问题讨论】:

  • 您可以groupby 'ID' 列并执行聚合:f.groupby('ID', as_index=False)['ID'].agg([np.count_nonzero, np.unique, np.max]),但不确定如何获得freq 计算
  • 我猜最接近的是f.groupby('ID', as_index=False)['ID'].agg([np.count_nonzero, np.unique, np.max, pd.Series.value_counts]).max()
  • @EdChum 结果似乎不太正确。对于上面的示例,count_nonzerovalue_counts 都返回 3390,而这应该是 7583。unique 返回 6422339;这应该是 68。
  • 不知道没有你的数据,但我认为使用 groupby 和 agg 是要走的路

标签: python python-3.x pandas


【解决方案1】:

我有点倾向于像你一样做,并即时转换为字符串以获得你想要的输出。我不认为性能损失会非常严重,并且怀疑您是否会经常使用describe() 是否足够重要。

也就是说,值得考虑如何存储一个真正作为标识符而不是值或度量的数字。如果它是唯一 ID(例如美式社会保险号),您只需将其存储为整数。如果它不是唯一的,那么将其存储为分类列可能是有意义的。唯一性越少(或重复次数越多),您作为分类存储的效果就越好。

这是一个简短的示例,其中 ID 的值可以从 1 到 4。

>>> df=pd.DataFrame({ 'id_int':np.random.randint(1,5,20) })
>>> df['id_cat'] = df.id_int.astype('category')

>>> df.dtypes

id_int       int64
id_cat    category

>>> df.memory_usage()

id_int    160
id_cat     52

如您所见,分类版本的 ID 使用了大约 1/3 的内存(这里的节省当然取决于重复的数量)。

如果你 describe() 它将被视为一个字符串对象。

>>> df.id_cat.describe()

count     20
unique     4
top        1
freq       8

【讨论】:

  • 这是一个非常好的提示!我仍在使用 Pandas,但我绝对可以看到将列存储为 category 的优势,具体取决于唯一性。特别是。当合并具有一对多关系的不同 DataFrame 时。
猜你喜欢
  • 1970-01-01
  • 2016-12-24
  • 2018-10-03
  • 2021-12-14
  • 2014-02-07
  • 1970-01-01
  • 2017-05-08
  • 2017-08-20
相关资源
最近更新 更多