pd.DataFrame.set_index 可以保留 dtype 吗?

Sam*_*fer 9 python pandas

我试图df.set_index以这样的方式调用,即dtype我 set_index 的列是 new index.dtype。不幸的是,在下面的示例中,set_index 更改了dtype.

df = pd.DataFrame({'a': pd.Series(np.array([-1, 0, 1, 2], dtype=np.int8))})
df['ignore'] = df['a']
assert (df.dtypes == np.int8).all() # fine
df2=  df.set_index('a')
assert df2.index.dtype == df['a'].dtype, df2.index.dtype
Run Code Online (Sandbox Code Playgroud)

是否可以避免这种行为?我的pandas版本是0.23.3

相似地,

new_idx = pd.Index(np.array([-1, 0, 1, 2]), dtype=np.dtype('int8'))
assert new_idx.dtype == np.dtype('int64')
Run Code Online (Sandbox Code Playgroud)

尽管 dtype 参数的文档说:“如果提供了实际的 dtype,如果它是安全的,我们会强制使用该 dtype。否则,将会引发错误。”

piR*_*red 1

尽管我在上面的评论中夸夸其谈,但这可能足以获得一个内存较低且从-1.

pandas.RangeIndex

采用启动和停止参数,例如range

df = df.set_index(pd.RangeIndex(-1, len(df) - 1))

print(df.index, df.index.dtype, sep='\n')
Run Code Online (Sandbox Code Playgroud)

这应该是非常有效的内存效率。

尽管它仍然是dtype int64(你应该想要的),但它占用的内存很少。

pd.RangeIndex(-1, 4000000).memory_usage()

84
Run Code Online (Sandbox Code Playgroud)

for i in range(1, 1000000, 100000):
  print(pd.RangeIndex(-1, i).memory_usage())

84
84
84
84
84
84
84
84
84
84
Run Code Online (Sandbox Code Playgroud)