【问题标题】:for if loop to categorize under conditionfor if 循环根据条件进行分类
【发布时间】:2019-02-23 08:03:38
【问题描述】:

我是python的新手,以前用过R。为此,我会使用as.factor并根据数字进行分类。

之前我尝试使用 replace 和 .loc 函数,以便根据条件在新列中提供新的类别值,但它只会在我想做的事情上失败。

最终我创建了以下非常简单的函数:

g['Category'] = ""

for i in g['NumFloorsGroup']:
    if i == '0-9' or i == '10-19':
        g['Category'] = 'LowFl'
    elif i == '50~':
        g['Category'] = 'HighFl'
    else:
        g['Category'] = 'NormalFl'

但是,当我运行该函数时,它只返回“LowFl”并且不会更正其他部分。我觉得我错过了什么。

数据信息如下:

<class 'pandas.core.frame.DataFrame'>
Int64Index: 596 entries, 128 to 595
Data columns (total 4 columns):
YearBuilt         596 non-null int64
NumFloorsGroup    596 non-null category
Count             596 non-null int64
Category          596 non-null object
dtypes: category(1), int64(2), object(1)

任何评论都会有所帮助!

bins = [0, 10, 20, 30, 40, 50, np.inf]
labels = ['0-9', '10-19', '20-29', '30-39', '40-49', '50~']
copy = original_data.copy()
copy['NumFloorsGroup'] = pd.cut(copy['NumFloors'], bins=bins, labels=labels, include_lowest=True)

g = (copy.groupby(['YearBuilt', 'NumFloorsGroup'])['YearBuilt']
        .count()
        .reset_index(name="Count")
                 .sort_values(by='Count', ascending=False))

以及只返回LowFl的部分

g['Category'] = ""

for i in g['NumFloorsGroup']:
    if i == '0-9' or i == '10-19':
        g['Category'] = 'LowFl'
    elif i == '50~':
        g['Category'] = 'HighFl'
    else:
        g['Category'] = 'NormalFl'

这会将所有类别返回为 LowFl

    YearBuilt   NumFloorsGroup  Count   Category
128 1920    0-9 90956   LowFl
171 1930    0-9 76659   LowFl
144 1925    0-9 70387   LowFl
237 1950    0-9 47237   LowFl
91  1910    0-9 46384   LowFl

【问题讨论】:

  • NumFloorsGroup列是如何创建的?
  • 我将 pd.cut 与基于另一列称为楼层数@jezrael 的垃圾箱和标签一起使用
  • 谢谢,可以看到吗?我认为最好的办法是改变它,给我一些时间来解决。
  • 我不确定如何共享整个数据,但我会在帖子中添加我所做的。谢谢! @jezrael

标签: python pandas for-loop if-statement


【解决方案1】:

你可以试试这个:

d = {
  "0-9": 'LowFl',
  "10-19": 'LowFl',
  "10-19": '50~',
}
g['NumFloorsGroup'].map(lambda key: d.get(key, 'NormalFl'))

【讨论】:

    【解决方案2】:

    我建议用新的 bin 和新标签更改 cut 函数,因为最好的方法是避免 pandas 中的循环,因为如果存在一些矢量化函数会很慢:

    df = pd.DataFrame({'Floors':[0,1,10,19,20,25,40, 70]})
    
    bins = [0, 10, 20, 30, 40, 50, np.inf]
    labels = ['0-9', '10-19', '20-29', '30-39', '40-49', '50~']
    
    df['NumFloorsGroup'] = pd.cut(df['Floors'], 
                                  bins=bins, 
                                  labels=labels,
                                  include_lowest=True)
    
    df['Category'] = pd.cut(df['Floors'], 
                            bins=[0, 19, 50, np.inf], 
                            labels=['LowFl','NormalFl','HighFl'],
                            include_lowest=True)
    
    print (df)
       Floors NumFloorsGroup  Category
    0       0            0-9     LowFl
    1       1            0-9     LowFl
    2      10            0-9     LowFl
    3      19          10-19     LowFl
    4      20          10-19  NormalFl
    5      25          20-29  NormalFl
    6      40          30-39  NormalFl
    7      70            50~    HighFl
    

    或将map 与带有fillna 的字典一起使用以将不在字典(NaNs)中的值替换为NormalFl

    d = { "0-9": 'LowFl',  "10-19": 'LowFl',"50+": 'HighFl'}
    df['Category']  = df['NumFloorsGroup'].map(d).fillna('NormalFl')
    

    【讨论】:

    • 哦,这部分我也应该使用 pd 切割!我想我的思考过程太复杂了。谢谢!
    • @tmhs - 很高兴能帮上忙!
    【解决方案3】:

    您的解决方案不起作用的原因是您没有迭代数据框。因此,要更正您的解决方案,而不是将其直接分配给列,而是将值附加到列表中,然后再将列表分配给数据框。

    category = []
    for i in g['NumFloorsGroup']:
        if i == '0-9' or i == '10-19':
            category.append('LowFl')
        elif i == '50~':
            category.append('HighFl')
        else:
            category.append('NormalFl')
    
    g.assign(category = category)
    

    【讨论】:

    • 啊,这就是为什么我总是必须创建列表并附加它们的原因。谢谢,在花了这么多时间想知道为什么它不起作用之后,我永远不会忘记这一点。
    猜你喜欢
    • 2016-08-19
    • 1970-01-01
    • 2021-02-17
    • 2012-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    相关资源
    最近更新 更多