Это довольно сложный вопрос для объяснения. Я пытаюсь очистить очень грязный набор данных, и это лучший способ сделать это, даже если это не так.
Я хочу объединить строки в отдельные столбцы, если они соответствуют определенным критериям. В частности, я хочу объединить все строки до следующей буквенной строки 4
. Я хочу применить эту функцию ко всем значениям, следующим за X
в df['A']
.
Это работает с использованием приведенного ниже кода, но я надеюсь включить оператор if/else
, где он объединяет конкретные 4
буквенные строки, но не другие. Может быть лучше отобразить это на примере:
import pandas as pd
d = ({
'A' : ['X','Include','X','Inclu','X','Incl','Y','X','Incl'],
'B' : ['','Excl','','de','','ude','No','','ude'],
'C' : ['','X','','keep','','Excl','No','','keep'],
'D' : ['','','','Excl','','ABC','Excl','','Excl'],
})
df = pd.DataFrame(data=d)
g = (df['A'] == 'X').cumsum()
m = g.duplicated() & (df['A'] == '') | (df['A'] == 'X')
df = df[~m.groupby(g).transform('all')]
maskX = df.iloc[:,0].apply(lambda x: x=='X')
maskX.index += 1
maskX = pd.concat([pd.Series([False]), maskX])
maskX = maskX.drop(len(maskX)-1)
mask = (df.iloc[:, 1:].astype(str).applymap(len) == 4).cumsum(1) == 0
for i,v in maskX.items():
mask.iloc[i,:] = mask.iloc[i,:].apply(lambda x: x and v)
df.A[maskX] = df.A + df.iloc[:, 1:][mask].fillna('').apply(lambda x: x.sum(), 1)
df.iloc[:, 1:] = df.iloc[:, 1:][~mask].fillna('')
Из:
A B C D
0 X
1 Include Excl X
2 X
3 Include keep Excl
4 X
5 Include Excl ABC
6 Y No No Excl
7 X
8 Include keep Excl
Это объединяет все columns
до 4
буквенной строки. Тем не менее, я надеюсь включить предостережение, в котором объединяются конкретные строки букв 4
. Например, я хочу объединить строку «keep» в column A
, что будет означать, что Excl
- последняя 4
строка букв.
Предполагаемая мощность:
A B C D
0 X
1 Include Excl X
2 X
3 Includekeep Excl
4 X
5 Include Excl ABC
6 Y No No Excl
7 X
8 Includekeep Excl