将具有一个单一分类值的列添加到 pandas 数据框

Adding a column with one single categorical value to a pandas dataframe

我有一个 pandas.DataFrame df,我想添加一个新列 col,只有一个值 "hello"。我希望此列是 dtype category 和单一类别 "hello"。我可以做到以下几点。

df["col"] = "hello"
df["col"] = df["col"].astype("catgegory")
  1. 我真的需要写 df["col"] 三次 次才能实现吗?
  2. 在第一行之后,我担心中间数据框 df 在新列转换为分类之前可能会占用大量 space。 (数据框相当大,有数百万行,值 "hello" 实际上是一个更长的字符串。)

在避免上述问题的同时,是否还有其他直接、“简短”的方法来实现此目的?

另一种解决方案是

df["col"] = pd.Categorical(itertools.repeat("hello", len(df)))

但它需要 itertoolslen(df) 的使用,我不确定内存使用情况。

这个解决方案肯定解决了第一点,第二点不确定:

df['col'] = pd.Categorical(('hello' for i in len(df)))

基本上

  • 我们先创建一个'hello'的生成器,长度等于df中的记录数
  • 然后我们将它传递给 pd.Categorical 使其成为分类列。

我们可以显式构建正确大小和类型的 Series,而不是通过 __setitem__ 隐式构建然后转换:

df['col'] = pd.Series('hello', index=df.index, dtype='category')

示例程序:

import pandas as pd

df = pd.DataFrame({'a': [1, 2, 3]})

df['col'] = pd.Series('hello', index=df.index, dtype='category')

print(df)
print(df.dtypes)
print(df['col'].cat.categories)
   a    col
0  1  hello
1  2  hello
2  3  hello

a         int64
col    category
dtype: object

Index(['hello'], dtype='object')

一个简单的方法是使用 df.assign 创建新变量,然后使用 df.astype 以及特定列的数据类型字典将数据类型更改为 category .

df = df.assign(col="hello").astype({'col':'category'})

df.dtypes
A         int64
col    category
dtype: object

这样你就不必创建一系列长度等于数据帧。您可以直接广播输入字符串,这样会节省更多时间和内存


如您所见,这种方法的可扩展性很强。您可以根据需要分配多个变量,一些变量也基于复杂的功能。然后根据需要为它们设置数据类型。

df = pd.DataFrame({'A':[1,2,3,4]})

df = (df.assign(col1 = 'hello',                    #Define column based on series or broadcasting
                col2 = lambda x:x['A']**2,         #Define column based on existing columns
                col3 = lambda x:x['col2']/x['A'])  #Define column based on previously defined columns
        .astype({'col1':'category',
                 'col2':'float'}))

print(df)
print(df.dtypes)
   A   col1  col2  col3
0  1  hello   1.0   1.0
1  2  hello   4.0   2.0
2  3  hello   9.0   3.0
3  4  hello  16.0   4.0


A          int64
col1    category  #<-changed dtype
col2     float64  #<-changed dtype
col3     float64
dtype: object