TL;DR :在熊猫中,根据给定的标准将一行分割成几行的最佳方法是什么,并根据拆分对值进行一些更改?
我有以下数据:
description value country
0 pen number 29143 for client X 100 France
1 pen num 99523 90 UK
2 pen 58123 and pen 88421 250 Spain
3 pen 10594 for Mr Smith 145 Italy
4 pen number 19534, 94212 and 55645 285 Germany我知道笔名是那个领域里唯一的5位码。我希望用多个ID“拆分”行,并平均分配值,同时保持其他字段相同:
id value country
0 29143 100 France
1 99523 90 UK
2 58123 125 Spain
3 88421 125 Spain
4 10594 145 Italy
5 19534 95 Germany
6 94212 95 Germany
7 55645 95 Germany我有一个解决这个问题的工作方法,但是它会创建多个切块,而且看起来一点也不像最好和最有效的方法。看起来是这样的:
(这使用basic re来标识字符串中的5位in )
首先,我创建"id“列并填充所有的单ID字段。
df['id'] = df['description'].apply(lambda x: re.findall('\d'*5,x)[0] if len(set(re.findall('\d'*5,x))) == 1 else None)然后我创建了索引字典:包含多个I的描述的I列表。
multiple_id_dict = {}
for i in df.index:
ids = list(set(re.findall('\d'*5, df.loc[i, 'description'])))
if len(ids) > 1:
multiple_id_dict[i] = ids之后,对于每个索引,我在dataframe中创建一行的字典,并将每个值转换为5次本身的列表(保留其他数据)。然后,我将正确的it和值分配给dict,将其转换为dataframe并将其附加到原始框架中。最后,删除原始行(现在是拆分行)。
for i in multiple_id_dict:
id_list = multiple_id_dict[i]
row_dict = df.loc[i].to_dict()
row_dict_sep = {x: [row_dict[x]]*len(id_list) for x in row_dict}
row_dict_sep['id'] = [x for x in id_list]
row_dict_sep['value'] = [row_dict['value']/len(id_list)]*len(id_list)
df = df.append(pd.DataFrame(row_dict_sep), sort=True)
df = df.drop(i)这似乎很纠结。是否有一种更简单或向量的“拆分”行的方法,使用某种"agg“来确定行中每个值的处理方式?
PS:复制/粘贴以获取示例数据的代码:
df = pd.DataFrame({'description': ['pen number 29143 for client X','pen num 99523','pen 58123 and pen 88421','pen 10594 for Mr Smith','pen number 19534, 94212 and 55645'],'value': [100, 90, 250, 145, 285], 'country':['France','UK','Spain','Italy','Germany']})发布于 2019-04-03 13:32:58
将Series.str.extractall与regex (\d{5})用于一列DataFrame的五位数,DataFrame.join用于原始计数和GroupBy.transform创建的除数,每个组的大小与origianl数据相同:
df1 = df.pop('description').str.extractall(r'(\d{5})').reset_index(level=1, drop=True)
print (df1)
0
0 29143
1 99523
2 58123
2 88421
3 10594
4 19534
4 94212
4 55645
df = df1.rename(columns={0:'id'}).join(df)
df['value'] /= df.groupby(level=0)['value'].transform('size')
df = df.reset_index(drop=True)
print (df)
id value country
0 29143 100.0 France
1 99523 90.0 UK
2 58123 125.0 Spain
3 88421 125.0 Spain
4 10594 145.0 Italy
5 19534 95.0 Germany
6 94212 95.0 Germany
7 55645 95.0 Germanyhttps://stackoverflow.com/questions/55496376
复制相似问题