0

我有一个数据框,其中三列表示用户可以订阅的三个国家区域。在三列中的每一列中都有一个国家列表(一些国家在所有三列中)

在另一个数据框中,我有一个用户列表和他们所在的国家/地区。

目的是确定用户在哪个区域(如果有),并说明他们是否允许在该国家/地区使用该服务。

df1 包含用户所在的国家和用户订阅的区域,以及其他字段。

df2 包含可用区域和该区域的国家列表以及其他字段。

df1.head()

name   alias3  status_y country    
Thetis Z1      active   Romania
Demis  Z1      active   No_country
Donis  Z1      active   Sweden
Rhona  Z3      active   Germany
Theau  Z2      active   Bangladesh

df2.head()

Zone 1   Zone 2  Zone 3
ALBANIA  ALBANIA ALBANIA
BELGIUM  BELGIUM BELGIUM
BULGARIA AUSTRIA AUSTRIA
NaN      CROATIA CROATIA
NaN      NaN     DENMARK

我已经编写了条件,列出了用户订阅的三个区域之一。

我写了选择用户所在国家的值,并检查该国家是否在用户订阅的区域中。

conditions = [
    (df1['alias3']=='Z1'),
    (df1['alias3']=='Z2'),
    (df1['alias3']=='Z3')
]

values = [
    df1['country'].str.upper().isin(country_zone['Zone 1']),
    df1['country'].str.upper().isin(country_zone['Zone 2']),
    df1['country'].str.upper().isin(country_zone['Zone 3'])
]

df1['valid_country'] = np.select(conditions, values)

有没有更好的方法在熊猫中做到这一点?

4

1 回答 1

0

一种简单的方法是:

def valid(sdf):
    zone = sdf.alias3.iat[0][-1]
    sdf["valid_country"] = sdf.country.str.upper().isin(df2[f"Zone {zone}"])
    return sdf

df1 = df1.groupby("alias3").apply(valid)
  • groupby df1alias3s 上然后
  • apply组的函数,检查upper组列中的 ed 国家名称country是否在相应列中,df2并将结果存储在名为的列中valid_country

另一种方法是稍作改动df2

df2.columns = df2.columns.str.replace("one ", "")
df2 = (
    df2.melt(var_name="alias3", value_name="country")
    .dropna()
    .assign(valid_country=True)
)
df2.country = df2.country.str.capitalize()
  • 将列名从 转换'Zone 1/2/3''Z1/2/3'
  • melt-ing:将Zone-column名称放入一个名为的列alias3中,并在一个名为的列中使用相应的国家名称country
  • 删除NaNs
  • 添加名为valid_countryall的列True
  • 国名大写

进而:

df1 = df1.merge(df2, on=["alias3", "country"], how="left")
df1.valid_country[df1.valid_country.isna()] = False
  • merge将结果留df1在列上alias3,然后country
  • False填写栏目中的缺失valid_country
于 2021-11-15T10:04:06.980 回答