【问题标题】:Pandas - Multi-Index Slicing/Setting With String WildcardsPandas - 使用字符串通配符进行多索引切片/设置
【发布时间】:2017-11-20 06:53:42
【问题描述】:

环顾四周,真的很难弄清楚这一点。我想要 在一行代码切片中并设置 pandas DataFrame 的多个单元格 到相同的值。

蓝色突出显示的部分是我要设置的部分。

这可以设置 - 但它只是一个值:

dframe2.ix[('virname1','int3', 'sysname1')]['Switchport_Voice_VLAN2'] = 'test'

这两个都可以切片,但不能设置:

dframe2.iloc[dframe2.index.get_level_values(0) == 'virname1' ]['Switchport_Voice_VLAN2']


dframe2.iloc['virname1', slice(None), 'sysname1']['Switchport_Voice_VLAN2']

有人可以建议是否有更好的方法来做到这一点?

>>> dframe2
                       Switchport_Voice_VLAN Switchport_Voice_VLAN2
virname1 int1 sysname1                horses                    NaN
virname2 int2 sysname2                   NaN                 horses
virname1 int2 sysname1                horses                 newval
         int3 sysname1                horses                   test
         int4 sysname1                horses                 newval

【问题讨论】:

  • 欢迎使用 SO,请使用 control+k 或四个前导空格格式化您的代码。
  • 完成 - 感谢您的提醒。

标签: python pandas dataframe slice multi-index


【解决方案1】:

使用df.loc 按标签选择行和/或列。

使用df.iloc 按序号索引选择行和/或列。

df.ix is deprecated 自 Pandas 版本 0.20.0 起,因此请避免使用它来确保您的代码不会过时。


在这种情况下,请使用 df.loc,因为 'virname1''sysname1''Switchport_Voice_VLAN2' 都是标签。

另请注意,在对 MultiIndex 进行切片时,index must be fully lexsorted:

df = df.sort_index(axis=0)

最后,使用df.loc,您可以同时对行和列进行切片:

df.loc[('virname1', slice(None), 'sysname1'), 'Switchport_Voice_VLAN2'] = 'test'

例如,

import numpy as np
import pandas as pd
index = pd.MultiIndex.from_arrays([
    ['virname{}'.format(i) for i in [1,2,1,1,1]],
    ['int{}'.format(i) for i in [1,2,2,3,4]],
    ['sysname{}'.format(i) for i in [1,2,1,1,1]]])
df = pd.DataFrame({'Switchport_Voice_VLAN':['horses',np.nan,'horses','horses','horses'], 
                   'Switchport_Voice_VLAN2':[np.nan,'horses','newval','test','newval']},
                  index=index)
df = df.sort_index(axis=0)
df.loc[('virname1', slice(None), 'sysname1'), 'Switchport_Voice_VLAN2'] = 'test'
print(df)

产量

                       Switchport_Voice_VLAN Switchport_Voice_VLAN2
virname1 int1 sysname1                horses                   test
         int2 sysname1                horses                   test
         int3 sysname1                horses                   test
         int4 sysname1                horses                   test
virname2 int2 sysname2                   NaN                 horses

【讨论】:

  • 完美!谢谢!作为临时解决方案,我复制了索引列,使其成为普通数据列,并使用与“==”值检查相同的 pd.loc 方法。但是您的解决方案让我可以直接在索引上执行此操作,并且更加优雅。
猜你喜欢
  • 2018-11-22
  • 1970-01-01
  • 2017-12-26
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
  • 2014-05-02
  • 2020-12-05
  • 1970-01-01
相关资源
最近更新 更多