如何在 Pandas 中根据索引级别设置行值?

3
我想向一个 Pandas 数据框添加一列,根据索引级别0和1设置值。例如,对于在级别0为homdelta列大于0的索引,将值设置为buy。对于在级别0为homdelta列小于0的索引,将值设置为sell。不同级别0的其他规则也有不同的设置值。请问如何实现?
>df
         delta
fut ABC  15284.233222
pos DEF  0.248976
    POL  0.002041
    ABC  0.043585
hom YTY  0.054100
    MNN -0.356873

这是期望的输出结果:

>df
         delta    new_col
fut ABC  15284.23 nan
pos DEF  0.248976 nan
    POL  0.002041 nan
    ABC  0.043585 nan
hom YTY  0.054100 buy
    MNN -0.356873 sell

我可以使用 loc 过滤数据框,但不确定如何创建新列。

df.loc[df.index.get_level_values(level=0) == 'hom'] > 0

         delta    new_col
hom YTY  0.054100 True
    MNN -0.356873 False
3个回答

3

由于你的数据已经有可用的索引,因此不需要进行任何布尔遮罩! 你可以简单地使用.loc来子集化并创建一个新的列。

import pandas as pd
import numpy as np

df.loc['hom', 'new_col'] = np.where(df.loc['hom', 'delta'] > 0, 'buy', 'sell')

print(df)
                delta new_col
fut ABC  15284.233222     NaN
pos DEF      0.248976     NaN
    POL      0.002041     NaN
    ABC      0.043585     NaN
hom YTY      0.054100     buy
    MNN     -0.356873    sell


一行代码解决,太棒了。 - Florent
不错的解决方案。你是不是使用了np.where,因为pd.DataFrame.where只允许替换一个值(而不是两个)? - Bill
这正是我为什么使用 np.where 的原因,如果 DataFrame.where(或 Series.where)可以替代两者,那我会使用它。如果你对纯粹的 pandas 替代方案感兴趣,你可以使用 .map({True: 'buy', False: 'sell})pd.Categorical.from_codes(bool_arr, ['sell', 'buy']) - Cameron Riddell

2
你可以使用 df.index.get_level_values 来获取索引值,然后使用 np.where/select 进行操作,例如:
is_hom = df.index.get_level_values(level=0) == 'hom'

df['new_col'] = np.select((~is_hom, df.delta > 0), (np.nan, 'buy'), 'sell')

有趣的方法,谢谢。由于某种原因,在 ! 处出现了 SyntaxError。如果我将其删除,则不会出现错误,但是值设置错误。 - Florent
2
! 应该改为 ~,以翻转布尔数组。 - Cameron Riddell

1

为了进行条件操作,我会将索引值移动到列中:

df.index = df.index.rename(names=['a', 'b'])
df = df.reset_index()
df['new_col'] = None

# Assignments
df.loc[(df.a == 'hom') & (df.delta > 0), 'new_col'] = 'buy'
df.loc[(df.a == 'hom') & (df.delta < 0), 'new_col'] = 'sell'

# Reset index
df = df.set_index(['a', 'b'])

结果:

                delta new_col
a   b                        
fut ABC  15284.233222    None
pos DEF      0.248976    None
    POL      0.002041    None
    ABC      0.043585    None
hom YTY      0.054100     buy
    MNN     -0.356873    sell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接