我想创建一个新列来对某个地址是住宅地址还是非住宅地址进行分类。
下面是原始数据框中的一列:
建筑物名称 |
---|
彩云(二)村凤泽楼 |
玛格丽特公主医院(非住院) |
我编写以下代码来创建一个新列,如果字符串“non-residential”在 Building_name 中,它将被归类为 Non-residential,否则将被归类为 Residential。
def build_cat(row):
if "(non-residential)" not in district_df['Building_name']:
return ("Residential")
if '(non-residential)' in district_df['Building_name']:
return ('Non_residential')
district_df['Building_category'] = district_df.apply(lambda row: build_cat(row), axis =1)
但是,about 函数将所有内容返回为 Residential。
建筑物名称 | Building_cateory |
---|---|
彩云(二)村凤泽楼 | 住宅 |
玛格丽特公主医院(非住院) | 住宅 |
感谢您能否让我知道我的代码有什么问题,或者是否有其他更有效的方法来获得相同的结果。
谢谢。
答案 0 :(得分:2)
或使用 np.where
作为 python if-else 三元运算符
cond = district_df['Building_name'].str.contains(r'\(non-residential\)')
district_df['Building_cateory'] = np.where(cond, 'Non_residential', 'Residential')
将函数应用到目标列 Building_name
。
def build_cat(x):
if "(non-residential)" not in x:
return "Residential"
else:
return 'Non_residential'
district_df['Building_category'] = district_df['Building_name'].map(build_cat)
答案 1 :(得分:2)
我选择添加这个社区维基,以供学习:
在我的 Jupyter Notebook 上,我比较了来自 @MayankPorwal 和 @Ferris 的答案。结果如下:
首先,str.contains
和 np.where
方法:
import pandas as pd
import numpy as np
df = pd.DataFrame({'Building_name': ['Fung Chak House, Choi Wan (II) Estate', 'Princess Margaret Hospital (non-residential)', 'Fung Chak 1', 'Fung Chak 2 (non-residential)', 'Fung Chak 3']})
df = pd.concat([df] * 10000, ignore_index=True)
def prop():
df['Building_cateory'] = np.where(df.Building_name.str.contains('non-residential'), 'Non-residential', 'residential')
现在,计时:
%timeit prop()
结果:
81.1 ms ± 15.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
另一方面,map()
方法:
import pandas as pd
import numpy as np
df = pd.DataFrame({'Building_name': ['Fung Chak House, Choi Wan (II) Estate', 'Princess Margaret Hospital (non-residential)', 'Fung Chak 1', 'Fung Chak 2 (non-residential)', 'Fung Chak 3']})
df = pd.concat([df] * 10000, ignore_index=True)
def prop():
def build_cat(x):
if "(non-residential)" not in x:
return "Residential"
else:
return 'Non_residential'
df['Building_category'] = df['Building_name'].map(build_cat)
现在,计时:
%timeit prop()
结果:
15.7 ms ± 1.13 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
因此,我们有一个明显的赢家!
答案 2 :(得分:1)
尝试以下 pandas
技巧以更快:
编辑
不,应用 lambda 更快。
使用 str.contains
方法计时:
2.34 ms ± 367 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
使用 apply-lambda 方法计时:
1.08 ms ± 138 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
使用 map()
方法最快:
742 µs ± 112 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
请注意,新列 Building_category
是在 #Line 1
import pandas as pd
df = pd.DataFrame({'Building_name': ['Fung Chak House, Choi Wan (II) Estate', 'Princess Margaret Hospital (non-residential)']})
# Line 1
df.loc[df[df['Building_name'].str.contains('(non-residential)')].index, 'Building_category'] = "Non_Residential"
# Line 2
df.loc[df[~df['Building_name'].str.contains('(non-residential)')].index, 'Building_category'] = "Residential"
print(df)
生成的输出:
Building_name Building_category
0 Fung Chak House, Choi Wan (II) Estate Residential
1 Princess Margaret Hospital (non-residential) Non_Residential
答案 3 :(得分:1)
使用numpy.where
:
In [1197]: import numpy as np
In [1198]: df['Building_cateory'] = np.where(df.Building_name.str.contains('non-residential'), 'Non-residential', 'residential')
In [1199]: df
Out[1199]:
Building_name Building_cateory
0 Fung Chak House, Choi_Wan (II) Estate residential
1 Princess Margaret Hospital (non-residential) Non-residential
答案 4 :(得分:0)
不确定这是最好的方法。但是,关于您得到的意外结果的确切问题,请将您的函数中的 district_df
更改为 row
。像这样。
要获得更好的方法,请查看下面的其他答案。克尔。
def build_cat(row):
if "(non-residential)" not in row['Building_name']:
return ("Residential")
if '(non-residential)' in row['Building_name']:
return ('Non_residential')
district_df['Building_category'] = district_df.apply(lambda row: build_cat(row), axis =1)
```