如何按“排除”条件创建行并扩展到现有数据帧?

2024-06-06 19:08:44 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧,其中一些行的Sold-To Country Name列的值为Not: XX XX XX,这意味着Sold-To Country Codes中除XX XX XX之外的其余部分将向映射的Reporting Country报告。你知道吗

另一个要求是,如果Sold-To Country Codenull(或NaN),它将捕获该SalesOrg中所有国家代码的所有收入。你知道吗

df_mapping = pd.DataFrame({'SalesOrg Code':['0001','0002','0002','0002','0002'],
                           'Reporting Country':['Spain','UK','UK','UK','Netherlands'],
                           'Sold-To Country Code':[np.nan,'IE','FR','IT','Ex:'],
                           'Sold-To Country Name':[np.nan,'Ireland','France','Italy','NOT: FR IE IT']})
SalesOrg Code   Reporting Country   Sold-To Country Code    Sold-To Country Name
0001            Spain                null                   null
0002            UK                   IE                     Ireland
0002            UK                   FR                     France
0002            UK                   IT                     Italy
0002            Netherlands          Ex:                    NOT: FR IE IT
.......

将有另一个数据框与全球国家代码的完整列表,我们可以在那里搜索其余的国家代码。你知道吗

数据帧示例:

df_countrylist = pd.DataFrame(["AF", "AX", "AL", "DZ", "AS", "AD", "AO", "AI", "AQ", "AG", "AR",
"AM", "AW", "AU", "AT", "AZ", "BS", "BH", "BD", "BB", "BY", "BE",
"BZ", "BJ", "BM", "BT", "BO", "BQ", "BA", "BW", "BV", "BR", "IO",
"BN", "BG", "BF", "BI", "CV", "KH", "CM", "CA", "KY", "CF", "TD",
"CL", "CN", "CX", "CC", "CO", "KM", "CG", "CD", "CK", "CR", "CI",
"HR", "CU", "CW", "CY", "CZ", "DK", "DJ", "DM", "DO", "EC", "EG",
"SV", "GQ", "ER", "EE", "ET", "FK", "FO", "FJ", "FI", "FR", "GF",
"PF", "TF", "GA", "GM", "GE", "DE", "GH", "GI", "GR", "GL", "GD",
"GP", "GU", "GT", "GG", "GN", "GW", "GY", "HT", "HM", "VA", "HN",
"HK", "HU", "IS", "IN", "ID", "IR", "IQ", "IE", "IM", "IL", "IT",
"JM", "JP", "JE", "JO", "KZ", "KE", "KI", "KP", "KR", "KW", "KG",
"LA", "LV", "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK",
"MG", "MW", "MY", "MV", "ML", "MT", "MH", "MQ", "MR", "MU", "YT",
"MX", "FM", "MD", "MC", "MN", "ME", "MS", "MA", "MZ", "MM", "NA",
"NR", "NP", "NL", "NC", "NZ", "NI", "NE", "NG", "NU", "NF", "MP",
"NO", "OM", "PK", "PW", "PS", "PA", "PG", "PY", "PE", "PH", "PN",
"PL", "PT", "PR", "QA", "RE", "RO", "RU", "RW", "BL", "SH", "KN",
"LC", "MF", "PM", "VC", "WS", "SM", "ST", "SA", "SN", "RS", "SC",
"SL", "SG", "SX", "SK", "SI", "SB", "SO", "ZA", "GS", "SS", "ES",
"LK", "SD", "SR", "SJ", "SZ", "SE", "CH", "SY", "TW", "TJ", "TZ",
"TH", "TL", "TG", "TK", "TO", "TT", "TN", "TR", "TM", "TC", "TV",
"UG", "UA", "AE", "GB", "US", "UM", "UY", "UZ", "VU", "VE", "VN",
"VG", "VI", "WF", "EH", "YE", "ZM", "ZW"])

最终,我想要这样:

SalesOrg Code   Reporting Country   Sold-To Country Code    Sold-To Country Name
0001            Spain                null (all)             null
0002            UK                   IE                     Ireland
0002            UK                   FR                     France
0002            UK                   IT                     Italy
0002            Netherlands          AT                     Austria 
0002            Netherlands          DK                     Denmark 
0002            Netherlands          NL                     Netherlands 
0002            Netherlands          BE                     Belgium 
0002            Netherlands          LT                     Lithuania 
0002            Netherlands          LX                     Latvia      
.......

对于SalesOrg#0002,如果Sold-To Country Code不是FR IE IT,其余的将向荷兰报告。所以我想为其余的国家代码创建行。你知道吗

有没有更好的方法来创建行并扩展到现有的数据帧中?你知道吗


Tags: to数据namecodeitfrcountrynull
2条回答

看看这能不能满足你的要求。你知道吗

df1['a'] = df1['Sold-To Name'].replace(regex=r'NOT:', value='').str.split(" ")
df1['a']= df1['a'].apply (lambda x : (np.setdiff1d(c_list,x)))
df1.loc[ df1['Sold-To Code']== 'Ex:', 'Sold-To Code' ] = df1['a']
df1=df1.explode('Sold-To Code')
df1.drop('a',axis=1,inplace=True)

细节

 df1['a'] = df1['Sold-To Name'].replace(regex=r'NOT:', value='').str.split(" ")

有了它,我们创建了一个新的列a,复制了列Sold-To Name的内容,删除了test'NOT:,将其余的拆分成一个列表

df1['a']= df1['a'].apply (lambda x : (np.setdiff1d(c_list,x)))

通过这个,我们将a中每一行的内容与contries列表(c\u列表应该是一个列表,而不是像您所拥有的数据帧)进行比较。你知道吗

df1.loc[ df1['Sold-To Code']== 'Ex:', 'Sold-To Code' ] = df1['a']

我们用Sold-To Code列的行替换a列的内容(这是Sold-To Name中其他国家的列表)

df1=df1.explode('Sold-To Code')

在pandas 0.25中,我们有pandas.DataFrame.explode,它可以用来将列列表中的每个项复制到单独的行中(其余的列将按原样复制)

df1.drop('a',axis=1,inplace=True)

我们删除列a,因为我们不再需要它了。你知道吗

这对我来说很好,在你这边检查一下,看看这对你是否也有效。你知道吗

如果你有熊猫0.25,那么Explode就是你需要的:

import numpy as np
import pandas as pd

df_mapping = pd.DataFrame({'SalesOrg Code':['0001','0002','0002','0002','0002'],
                           'Reporting Country':['Spain','UK','UK','UK','Netherlands'],
                           'Sold-To Country Code':[np.nan,'IE','FR','IT','Ex:'],
                           'Sold-To Country Name':[np.nan,'Ireland','France','Italy','NOT: FR IE IT']})

country_set = {"AF", "AX", "AL", "DZ", "AS", "AD", "AO", "AI", "AQ", "AG", "AR",
"AM", "AW", "AU", "AT", "AZ", "BS", "BH", "BD", "BB", "BY", "BE",
"BZ", "BJ", "BM", "BT", "BO", "BQ", "BA", "BW", "BV", "BR", "IO",
"BN", "BG", "BF", "BI", "CV", "KH", "CM", "CA", "KY", "CF", "TD",
"CL", "CN", "CX", "CC", "CO", "KM", "CG", "CD", "CK", "CR", "CI",
"HR", "CU", "CW", "CY", "CZ", "DK", "DJ", "DM", "DO", "EC", "EG",
"SV", "GQ", "ER", "EE", "ET", "FK", "FO", "FJ", "FI", "FR", "GF",
"PF", "TF", "GA", "GM", "GE", "DE", "GH", "GI", "GR", "GL", "GD",
"GP", "GU", "GT", "GG", "GN", "GW", "GY", "HT", "HM", "VA", "HN",
"HK", "HU", "IS", "IN", "ID", "IR", "IQ", "IE", "IM", "IL", "IT",
"JM", "JP", "JE", "JO", "KZ", "KE", "KI", "KP", "KR", "KW", "KG",
"LA", "LV", "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK",
"MG", "MW", "MY", "MV", "ML", "MT", "MH", "MQ", "MR", "MU", "YT",
"MX", "FM", "MD", "MC", "MN", "ME", "MS", "MA", "MZ", "MM", "NA",
"NR", "NP", "NL", "NC", "NZ", "NI", "NE", "NG", "NU", "NF", "MP",
"NO", "OM", "PK", "PW", "PS", "PA", "PG", "PY", "PE", "PH", "PN",
"PL", "PT", "PR", "QA", "RE", "RO", "RU", "RW", "BL", "SH", "KN",
"LC", "MF", "PM", "VC", "WS", "SM", "ST", "SA", "SN", "RS", "SC",
"SL", "SG", "SX", "SK", "SI", "SB", "SO", "ZA", "GS", "SS", "ES",
"LK", "SD", "SR", "SJ", "SZ", "SE", "CH", "SY", "TW", "TJ", "TZ",
"TH", "TL", "TG", "TK", "TO", "TT", "TN", "TR", "TM", "TC", "TV",
"UG", "UA", "AE", "GB", "US", "UM", "UY", "UZ", "VU", "VE", "VN",
"VG", "VI", "WF", "EH", "YE", "ZM", "ZW"}

然后找到需要“展开”到新行的位置:

mask = df_mapping['Sold-To Country Name'].str.contains("NOT:").fillna(False)
df_mapping.loc[mask, 'Sold-To Country Code'] = df_mapping.loc[mask, 'Sold-To Country Name'].apply(lambda x: list(country_set - set(x.split(" ")[1:])))
df_mapping = df_mapping.explode('Sold-To Country Code')
df_mapping.reset_index(drop=True, inplace=True)

当然,您必须使用另一个数据框将国家代码与国家名称进行匹配。你知道吗

相关问题 更多 >