【问题标题】:Pandas - Create a Categorical object with categories of the same priorityPandas - 创建具有相同优先级的类别的分类对象
【发布时间】:2019-04-02 22:44:59
【问题描述】:

假设我想订购某些类别。例如,颜色:

Green = Yellow > Red

这里,绿色和黄色的优先级相同,高于红色的优先级。是否有可能创建这样的分类对象?我可以这样做吗?

df['Color'] = pd.Categorical(df['Color'], categories=[('Green', 'Yellow'), 'Red'], ordered=True)

元组('Green', 'Yellow')表示绿色和黄色的优先级相同。

示例输入数据框:

ID    Color
1     Red
2     Yellow
1     Yellow
3     Red
1     Green
2     Red

预期输出是没有重复 ID 的 DataFrame,考虑到颜色的优先级:

ID    Color
1     Yellow
2     Yellow
3     Red

【问题讨论】:

  • 使用上一题的地图版本,给绿色和黄色都赋值相同的值(我能想到的)
  • @anky_91 不起作用
  • 您能否提供一个示例输入 df 列和预期的 df 列
  • @RahulAgarwal 我已经编辑了问题
  • 检查我的答案!!

标签: python pandas


【解决方案1】:

可以解决如下:

由于提供的信息,我们会将黄色和绿色视为相同的优先级。

我们将在这里使用以下方法。

DataFrame.apply 允许我们沿轴应用函数 Docs: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.apply.html

sorted 允许我们通过指定键以我们想要的顺序对列表进行排序。文档:https://docs.python.org/3/library/functions.html#sorted 你也可以用 list.sort 做同样的事情,但 sorted 给出了列表的新对象。

import pandas as pd
#create DataFrame
df=pd.DataFrame({'ID':[1,2,1,3,1,2],'Color':['Red','Yellow','Yellow','Red','Green','Red']})

"""
Creating a set_priority list by putting the colors with the highest priority at 
the top and the lowest priority or no priority at the bottom. This list would be 
used as the key in the sorted function below.

Below I am grouping the df with the Id and making a list of all the colors attached to the same ID. Then I am sorting the list based on the priority and choosing the first element from that list as it was asked in the question
"""

set_priority=['Yellow','Green' ,'Red']
result=df.groupby('ID')['Color'].apply(lambda x: sorted(list(x), key=lambda y: set_priority.index(y))[0]).reset_index()

结果

   ID   Color
0   1  Yellow
1   2  Yellow
2   3     Red

【讨论】:

  • 这个解决方案似乎有效,但你能详细解释一下这段代码的 sn-p 究竟是做什么的吗?因为每当我有一个更大的数据集和一些其他颜色时,当调用带有result 的代码行时,我会得到一个ValueError: Purple is not in list。 (除了我的数据中的这三种颜色之外,我还有一些其他颜色)。所以我无法弄清楚问题是什么
  • @HidayetRzayev 你必须在你想要的优先级中添加列表“set_priority”中的所有颜色。比如你说的信息中,Green = Yellow > Red,我翻译成[Green,Yellow,Red]。现在如果你也有紫色,那么它的优先级就像绿色 = 黄色 > 紫色 > 红色,那么更新后的“set_priority”将是 [绿色、黄色、紫色、红色]。希望这会有所帮助,如果没有,请告诉我!
  • 问题是,那些其他颜色没有任何优先级。就我而言,我只考虑绿色、黄色和红色,而忽略所有其他颜色
  • 好的,那么如果一个 ID 只包含一种非优先级的颜色,那么您将忽略该颜色,或者您将如何处理它。您可以根据此编辑问题吗?我现在能想到的一种解决方案是将其他所有内容放在“红色”之后。
  • @HidayetRzayev 我在上面解释过!
【解决方案2】:

使用分类时,可以指定自定义排序顺序。这并没有给出问题中所需的关系,但也许sort_dict 可以用来模拟这样的事情。

import pandas as pd

colors = ["Green", "Red", "Yellow", "Yellow", "Red", "Green"]
df = pd.DataFrame({"Color":colors})
sort_dict = {"Yellow":-1, "Green":1, "Red":6}
df["colorcat"] = pd.Categorical(df['Color'], categories=sorted(sort_dict, key=sort_dict.get), ordered=True)
print(df.sort_values("colorcat"))

    Color colorcat
2  Yellow   Yellow
3  Yellow   Yellow
0   Green    Green
5   Green    Green
1     Red      Red
4     Red      Red

在类别中放置一个元组似乎不起作用。

import pandas as pd

colors = ["Green", "Red", "Yellow", "Yellow", "Red", "Green"]
df = pd.DataFrame({"Color":colors})
df["colorcat"] = pd.Categorical(df['Color'], categories=[("Green", "Yellow"), "Red"], ordered=True)
print(df.sort_values("colorcat"))

    Color colorcat
1     Red      Red
4     Red      Red
0   Green      NaN
2  Yellow      NaN
3  Yellow      NaN
5   Green      NaN

【讨论】:

    【解决方案3】:
    import pandas as pd
    # Create an example dataframe
    data = {'ID': ['1' , '2', '1', '3', '1', '2'], 
            'Color': ['Red' , 'Yellow' , 'Yellow' , 'Red', 'Green', 'Red']}
    df1 = pd.DataFrame(data)
    
    a = df1.join(df1.groupby(['ID'])['Color'].apply(set).rename('m'),
                 on=['ID'])['m']
    
    m1 = (a == set({'Green', 'Yellow', 'Red'})) | (a == set({'Green', 'Yellow'}))| (a == set({'Red', 'Yellow'}))
    m2 = a == set({'Red'})
    
    m4 = df1['Color'] == 'Yellow'
    m5 = df1['Color'] == 'Red'
    
    df1 = df1[(m1 & m4) | (m2 & m5) ]
    

    打印(df1)

        Color ID
    1  Yellow  2
    2  Yellow  1
    3     Red  3
    

    【讨论】:

    • @hidayetRzayev:你试过我的解决方案了吗?告诉我它是否不起作用?
    • 很遗憾没有,它删除的行数超过了在更大的数据集中应该删除的行数
    • 不明白如何......复制你在原始df中的相同变量,我可以相应地修改
    • Kartikeya Sharma 的答案适用于这个特定问题
    猜你喜欢
    • 1970-01-01
    • 2021-12-16
    • 2018-02-28
    • 1970-01-01
    • 2016-03-02
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多