我有这个数据框架:
SRC Coup Vint Bal Mar Apr May Jun Jul BondSec
0 JPM 1.5 2021 43.9 5.6 4.9 4.9 5.2 4.4 FNCL
1 JPM 1.5 2020 41.6 6.2 6.0 5.6 5.8 4.8 FNCL
2 JPM 2.0 2021 503.9 7.1 6.3 5.8 6.0 4.9 FNCL
3 JPM 2.0 2020 308.3 9.3 7.8 7.5 7.9 6.6 FNCL
4 JPM 2.5 2021 345.0 8.6 7.8 6.9 6.8 5.6 FNCL
5 JPM 4.5 2010 5.7 21.3 20.0 18.0 17.7 14.6 G2SF
6 JPM 5.0 2019 2.8 39.1 37.6 34.6 30.8 24.2 G2SF
7 JPM 5.0 2018 7.3 39.8 37.1 33.4 30.1 24.2 G2SF
8 JPM 5.0 2010 3.9 23.3 20.0 18.6 17.9 14.6 G2SF
9 JPM 5.0 2009 4.2 22.8 21.2 19.5 18.6 15.4 G2SF
我想复制所有以FNCL
为BondSec
的行,并将这些新的重复行中BondSec
的值重命名为FGLMC
。我可以用下面的代码完成其中的一半:
if "FGLMC" not in jpm['BondSec']:
is_FNCL = jpm['BondSec'] == "FNCL"
FNCL_try = jpm[is_FNCL]
jpm.append([FNCL_try]*1,ignore_index=True)
但是,如果我尝试在同一行中实现对BondSec
值的更改,如下所示:
jpm.append(([FNCL_try]*1).assign(**{'BondSecurity': 'FGLMC'}),ignore_index=True)
我得到以下错误:AttributeError: 'list' object has no attribute 'assign'
此外,我希望根据索引条件插入重复的行,而不仅仅是作为附加行插入底部。条件不能仅仅是一个行位置,因为这将不得不在具有不同行数的未来文件中工作。因此,我想在BondSec
列值从FNCL
更改为FNCI
的位置插入重复的行(FNCI
没有显示在这里,但基本上它将位于FNCL
的最后一行下方)。我假设这可以通过np.where
函数调用来完成,但我不确定如何实现。
我最终也想用FNCI
作为BondSec
值的行做同样的过程(复制它们并将BondSec
值转换为FGCI
,并在最后一行的索引位置插入FNCI
作为值)。
我建议使用一个辅助函数来处理所有的重复:
def duplicate_and_rename(df, target, value):
return pd.concat([df, df[df["BondSec"] == target].assign(BondSec=value)])
然后
for target, value in (("FNCL", "FGLMC"), ("FNCI", "FGCI")):
df = duplicate_and_rename(df, target, value)
然后,您可以对BondSec
列进行分类,并使用自定义顺序:
ordering = ["FNCL", "FGLMC", "FNCI", "FGCI", "G2SF"]
df["BondSec"] = pd.Categorical(df["BondSec"], ordering).sort_values()
df = df.reset_index(drop=True)
或者,您可以使用字典进行排序,如本答案所述。