【问题标题】:Filtering pandas df with level values使用级别值过滤 pandas df
【发布时间】:2019-06-04 04:04:28
【问题描述】:

我有以下熊猫df:

df
                        price           max    maxperhour
Site  Commodity Type                        
Mid   Biomass   Stock     6.0  1.500000e+15  1.500000e+15
      CO2       Env       0.0  1.500000e+15  1.500000e+15
      Coal      Stock     7.0  1.500000e+15  1.500000e+15
      Elec      Demand    NaN           NaN           NaN
      Gas       Stock    27.0  1.500000e+15  1.500000e+15
      Hydro     SupIm     NaN           NaN           NaN
      Lignite   Stock     4.0  1.500000e+15  1.500000e+15
      Solar     SupIm     NaN           NaN           NaN
      Wind      SupIm     NaN           NaN           NaN

Site == 'Mid'Type == ('Stock' or 'Demand') 时,我想过滤上述df 并创建一个Commodity 项目列表作为列表。

因此应该使用一些 pandas 过滤功能创建以下列表:

df.somefunction()
['Biomass', 'Coal', 'Gas', 'Lignite', 'Elec']

我将如何实现这一目标?


最后,如果可能的话,我希望将'Elec' 作为最后一个元素,我的意思是;创建列表时,'Elec' 可能是列表的第三个元素,例如:

['Biomass', 'Coal', 'Elec', 'Gas', 'Lignite']

但是,如果我能将'Elec' 作为最后一个元素,那将是最好的:

['Biomass', 'Coal', 'Gas', 'Lignite', 'Elec']

因为它是唯一带有Type == 'Demand'的元素


来自@jezrael

df[(df.index.get_level_values('Site') == 'Mid') & (df.index.get_level_values('Type') == 'Stock')].index.remove_unused_levels().get_level_values('Commodity').tolist()

【问题讨论】:

  • 您认为需要将过滤值的数量与Mid, StockMid, Demand 进行比较,并按输出的长度需要连接在一起吗?

标签: python pandas list filter levels


【解决方案1】:

MultiIndex 的解决方案:

m1 = (df.index.get_level_values('Site') == 'Mid')
m2 = (df.index.get_level_values('Type') == 'Stock')
m3 = (df.index.get_level_values('Type') == 'Demand')

idx1 = df[m1 & m2].index.remove_unused_levels().get_level_values('Commodity')
idx2 = df[m1 & m3].index.remove_unused_levels().get_level_values('Commodity')

idx = idx1.append(idx2)
print (idx)
Index(['Biomass', 'Coal', 'Gas', 'Lignite', 'Elec'], dtype='object', name='Commodity')

列的替代方案:

df1 = df.reset_index()
m1 = (df1['Site'] == 'Mid')
m2 = (df1['Type'] == 'Stock')
m3 = (df1['Type'] == 'Demand')

idx1 = df1.loc[m1 & m2, 'Commodity']
idx2 = df1.loc[m1 & m3, 'Commodity']

idx = idx1.append(idx2).tolist()
print (idx)
['Biomass', 'Coal', 'Gas', 'Lignite', 'Elec']

【讨论】:

  • 你正在超过第二个要求的水平长度,但如果需求长于它不会起作用,但仍然感谢你的努力
  • @oakca - 所以不确定是否理解,背后的逻辑是什么?不是输出长度?
  • 好吧,问题太具体不是你的错......背后的逻辑是需求元素应该始终放在最后,但没关系。我在第一个错误中遇到了一个奇怪的错误,因为我不想创建 m1 和 m2,而是通过 df[df.index.get_level_values('Site') == 'Mid' & df.index.get_level_values('Type').isin(['Stock', 'Demand'])].index.remove_unused_levels().get_level_values('Commodity') 在 1 行中编写了所有这些错误,错误是
  • *** TypeError: ufunc 'bitwise_and' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
  • @oakca - 是的,有问题,需要()data['commodity'][(data['commodity'].index.get_level_values('Site') == 'Mid') & (data['commodity'].index.get_level_values('Type') == 'Stock')].index.remove_unused_levels().get_level_values('Commodity')
猜你喜欢
  • 2019-07-26
  • 2022-01-25
  • 2023-02-06
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
  • 2021-09-04
  • 2017-02-26
相关资源
最近更新 更多