我有一个数据集,其中一种数据类型分布在多个列中。我想将这些减少到一个列。我有一个函数可以完成此操作,但这是一个繁琐的过程,我希望有一种更简洁的方法来完成此操作。这是我的数据的玩具样本:
UID COMPANY EML MAI TEL
273 7UP nan nan TEL
273 7UP nan MAI nan
906 WSJ nan nan TEL
906 WSJ EML nan nan
736 AIG nan MAI nan
我想做的事情:
UID COMPANY CONTACT_INFO
273 7UP MT
906 WSJ ET
736 AIG M
我已经通过编写一个将 EML、MAI 或 TEL 转换为素数、聚合结果然后转换的函数解决了这个问题组成联系类型的总和。这有效,而且相当快。这是一个示例:
def columnRedux(df):
newDF = df.copy()
newDF.fillna('-', inplace=True)
newDF['CONTACT_INFO'] = newDF['EML'] + newDF['MAI'] + newDF['TEL']
newDF.replace('EML--', 7, inplace=True)
newDF.replace('-MAI-', 101, inplace=True)
newDF.replace('--TEL', 1009, inplace=True)
small = newDF.groupby(['UID', 'COMPANY'], as_index=False)['CONTACT_INFO'].sum()
small.replace(7, 'E', inplace=True)
small.replace(101, 'M', inplace=True)
small.replace(108, 'EM', inplace=True)
small.replace(1009, 'T', inplace=True)
small.replace(1016, 'ET', inplace=True)
small.replace(1110, 'MT', inplace=True)
small.replace(1117, 'EMT', inplace=True)
return small
df1 = pd.DataFrame(
{'EML' : [np.nan, np.nan, np.nan, 'EML', np.nan, np.nan, 'EML', np.nan, np.nan, 'EML', 'EML', np.nan],
'MAI' : [np.nan, 'MAI', np.nan, np.nan, 'MAI', np.nan, np.nan, np.nan, 'MAI', np.nan, np.nan, 'MAI'],
'COMPANY' : ['7UP', '7UP', 'UPS', 'UPS', 'UPS', 'WSJ', 'WSJ', 'TJX', 'AIG', 'CDW', 'HEB', 'HEB'],
'TEL' : ['TEL', np.nan, 'TEL', np.nan, np.nan, 'TEL', np.nan, 'TEL', np.nan, np.nan, np.nan, np.nan],
'UID' : [273, 273, 865, 865, 865, 906, 906, 736, 316, 458, 531, 531]},
columns=['UID', 'COMPANY', 'EML', 'MAI', 'TEL'])
cleanDF = columnRedux(df1)
我的问题是我有几个数据集,每个数据集都有自己的一组“宽”列。有些有 5 个以上的列要减少。对所有变体的转换进行硬编码并非易事。有没有更简洁的方法来完成此操作?
请您参考如下方法:
也许不是“最好”的解决方案。但是一种方法是使用一个简单的 groupby 并对包含的元素进行条件处理:
df = df.groupby(['UID','COMPANY'])[['EML','MAI','TEL']]\
.apply(lambda x: ''.join(sorted([i[0] for y in x.values for i in y if pd.notnull(i)])))\
.reset_index()\
.rename(columns={0:'CONTACT_INFO'})
或者另一种方法是将分组数据帧转换为 str 类型并替换字符串和总和。我会说非常可读。
m = {
'nan':'',
'EML':'E',
'MAI':'M',
'TEL':'T'
}
df = df.groupby(['UID','COMPANY'])[['EML','MAI','TEL']]\
.apply(lambda x: x.astype(str).replace(m).sum().sum())\
.reset_index()\
.rename(columns={0:'CONTACT_INFO'})
完整示例:
import pandas as pd
import numpy as np
data = '''\
UID COMPANY EML MAI TEL
273 7UP nan nan TEL
273 7UP nan MAI nan
906 WSJ nan nan TEL
906 WSJ EML nan nan
736 AIG nan MAI nan'''
fileobj = pd.compat.StringIO(data)
df = pd.read_csv(fileobj, sep='\s+').replace('NaN',np.nan)
# use a nested list comprehension to flatten the array and remove nans.
df = df.groupby(['UID','COMPANY'])[['EML','MAI','TEL']]\
.apply(lambda x: ''.join(sorted([i[0] for y in x.values for i in y if pd.notnull(i)])))\
.reset_index()\
.rename(columns={0:'CONTACT_INFO'})
print(df)
返回:
UID COMPANY CONTACT_INFO
273 7UP MT
736 AIG M
906 WSJ ET
dtype: object
