样本DF:
我有一个df,其中包含Zone
,New_Zone
,Country
,New_Region
和Currency
之类的列
Currency
列的值类似EUR
,AUD
,BLR
,RUB
Zone
列的值类似EU
,Africa
,NAZ
New_Zone
的值类似于EU
,Europe
,EUROPE
,Africa
,NAZ
,AFRICA
Country
的值类似于Australia
,Brazil
,Russia
,Ukraine
,USA
New_Region
的值类似于Australia
,Brazil
,USA
因此,列Zone
和New_Zone
包含几乎相似的值,列New_Region
和Country
包含几乎相似的值
询问:
我想在满足以下条件的情况下创建一个名为Currency_Match
的新列:
EUR
,则是其他否AUD
,则为其他否BLR
,则为其他否如果国家/地区为韩国 OR (逻辑)新地区为韩国 AND (逻辑)货币为KRW
,则其他为否
如果区域是非洲 OR (逻辑)New_Zone是非洲或非洲,则 AND (逻辑)货币是NGN
,则是,否则是< / p>
6如果Zone是NAZ OR (逻辑)New_Zone是NAZ,则 AND (逻辑)货币是USD
,则是其他
7如果国家/地区是俄罗斯,乌克兰 OR (逻辑)新地区是俄罗斯 AND (逻辑)货币是RUB
,则是否
我总共有上述7种情况
代码:
df['Currency_Match']=df.apply(lambda row: "Yes" if (((row['Zone'] == "EU")|(row['New_Zone'] =='Europe')|(row['New_Zone'] =='EU')|(row['New_Zone'] =='EUROPE'))
& (row["Contract - Original Currency Code"] == "EUR"))
else 'No',axis=1)
问题:
上面的代码运行良好,但是当我编写类似这样的其他条件时,它会一次又一次地更新列。
他们有其他方法可以做到吗,而且也比这麻烦吗
答案 0 :(得分:2)
为可读代码的单独行创建每个条件,按|
或&
进行按链OR
或AND
的链接,以形成最终掩码并传递到numpy.where
:
m1 = (df['Zone'] == "EU")|(df['New_Zone'].isin(['Europe','EUROPE','EU'])
m2 = (df["Contract - Original Currency Code"] == "EUR")
m3 = (df['Region'] == "Australia")|(df['New_Region'] =='Australia')
m4 = (df["Contract - Original Currency Code"] == "AUD")
m5 = (df['Region'] == "Brazil")|(df['New_Region'] =='Brazil')
m6 = (df["Contract - Original Currency Code"] == "BLR")
mask = (m1 & m2) | (m3 & m4) | (m5 & m6)
df['Currency_Match'] = np.where(mask, "Yes", 'No')
编辑:对于动态解决方案,请按货币创建带有区域和区域列表的字典,然后传递到dict comprehension
中的logical_or.reduce
:
#zone dict
d1 = {'EUR':['Europe','EUROPE','EU'],'NGN':['Africa','AFRICA'],'USD':['NAZ']}
#region dict
d2 = {'AUD':['Australia'], 'BLR':['Brazil'],'KRW':['Korea'],'RUB':['Russia','Ukraine']}
m1 = [(df['Zone'].isin(v) | df['New_Zone'].isin(v)) &
(df["Contract - Original Currency Code"] == k)
for k, v in d1.items()]
print (m1)
m2 = [(df['Region'].isin(v) | df['New_Region'].isin(v)) &
(df["Contract - Original Currency Code"] == k)
for k, v in d2.items()]
print (m2)
mask = np.logical_or.reduce(m1) | np.logical_or.reduce(m2)
df['Currency_Match'] = np.where(mask, "Yes", 'No')