#python-3.x #pandas #dataframe #split
#python-3.x #pandas #dataframe #разделить
Вопрос:
У меня есть следующие данные
Index Data
0 100CO
1 50CO-50PET
2 98CV-2EL
3 50CV-50CO
. .
. .
. .
Я должен создать формат разделения данных на разные столбцы, каждый со своим собственным заголовком и их значениями, результат должен быть таким, как показано ниже:
Index Data CO PET CV EL
0 100CO 100 0 0 0
1 50CO-50PET 50 50 0 0
2 98CV-2EL 0 0 98 2
3 50CV-50CO 50 0 50 0
. .
. .
. .
Данные не ограничены CO / PET / CV / EL, потребуется столько столбцов, сколько необходимо, каждый из которых отображает соответствующее значение.
.str.split('-', expand=True)
Функция будет только разделять данные и сохранять все первые значения в одном столбце и не переименовывать каждый столбец.
Есть ли способ реализовать это на Python?
Ответ №1:
Вы могли бы сделать:
df.Data.str.split('-').explode().str.split(r'(?<=d)(?=D)',expand = True).
reset_index().pivot('index',1,0).fillna(0).reset_index()
1 Index CO CV EL PET
0 0 100 0 0 0
1 1 50 0 0 50
2 2 0 98 2 0
3 3 50 50 0 0
Комментарии:
1. Привет, спасибо за ответ. К сожалению, при объединении с исходной базой данных индекс не совпадает.
2. вы просто удаляете
index
имя
Ответ №2:
Идея заключается в том, чтобы сначала разделить значения на -
, затем извлечь значения numbers и no numbers в кортежи, добавить в список и преобразовать в словари. Он передается в понимании списка в DataFrame
cosntructor, заменяется ошибочными значениями и преобразуется в числовой:
import re
def f(x):
L = []
for val in x.split('-'):
k, v = re.findall('(d )(D )', val)[0]
L.append((v, k))
return dict(L)
df = df.join(pd.DataFrame([f(x) for x in df['Data']], index=df.index).fillna(0).astype(int))
print (df)
Data CO PET CV EL
0 100CO 100 0 0 0
1 50CO-50PET 50 50 0 0
2 98CV-2EL 0 0 98 2
3 50CV-50CO 50 0 50 0
Если в данных существуют некоторые значения без числа или решение только для числа должно быть изменено на более общее, например:
print (df)
Data
0 100CO
1 50CO-50PET
2 98CV-2EL
3 50CV-50CO
4 AAA
5 20
def f(x):
L = []
for val in x.split('-'):
extracted = re.findall('(d )(D )', val)
if len(extracted) > 0:
k, v = extracted[0]
L.append((v, k))
else:
if val.isdigit():
L.append(('No match digit', val))
else:
L.append((val, 0))
return dict(L)
df = df.join(pd.DataFrame([f(x) for x in df['Data']], index=df.index).fillna(0).astype(int))
print (df)
Data CO PET CV EL AAA No match digit
0 100CO 100 0 0 0 0 0
1 50CO-50PET 50 50 0 0 0 0
2 98CV-2EL 0 0 98 2 0 0
3 50CV-50CO 50 0 50 0 0 0
4 AAA 0 0 0 0 0 0
5 20 0 0 0 0 0 20
Ответ №3:
Попробуйте это:
import pandas as pd
import re
df = pd.DataFrame({'Data':['100CO', '50CO-50PET', '98CV-2EL', '50CV-50CO']})
split_df = pd.DataFrame(df.Data.apply(lambda x: {re.findall('[A-Z] ', el)[0] : re.findall('[0-9] ', el)[0]
for el in x.split('-')}).tolist())
split_df = split_df.fillna(0)
df = pd.concat([df, split_df], axis = 1)
Комментарии:
1. Привет, спасибо за ответ. К сожалению, при объединении с исходной базой данных индекс не совпадает.