Разбор неструктурированных данных в фрейме данных Pandas - PullRequest
0 голосов
/ 09 ноября 2018

У меня в настоящее время есть следующая структура данных в кадре данных pandas после импорта файла * .txt через read_csv:

    label   text
0   ###24293578 NaN
1   INTRO   Some text...
2   METHODS Some text...
3   METHODS Some text...
4   METHODS Some text...
5   RESULTS Some text...
6   ###24854809 NaN
7   BACKGROUND  Some text...
8   INTRO   Some text...
9   METHODS Some text...
10  METHODS Some text...
11  RESULTS Some text...
12  ###25165090 NaN
13  BACKGROUND  Some text...
14  METHODS Some text...
...

Что мне нравится делать, так это запускать индекс для каждой строки, извлекаемый из идентификатора, помеченного "###":

id        label       text
24293578  INTRO       Some text...
24293578  METHODS     Some text...
24293578  ...         ...
24854809  BACKGROUND  Some text...
24854809  ...         ...
25165090  BACKGROUND  Some text...
25165090  ...         ...

В настоящее время я использую следующий код для преобразования данных:

m = df['label'].str.contains("###", na=False) 
df['new'] = df['label'].where(m).ffill()
df = df[df['label'] != df['new']].copy()
df['label'] = df.pop('new').str.lstrip('#') + ' ' + df['label']
df[['id','area']] = df['label'].str.split(' ',expand=True)
df = df.drop(columns=['label'])
df

Из:

    text            id          area
1   Some text...    24293578    OBJECTIVE
...
6   Some text...    24854809    BACKGROUND
...

Это делает работу , но я чувствую, что это не лучший подход. Есть ли способ написать более чистый код или сделать его более эффективным? Мне также любопытно, может ли функция a быть непосредственно встроена в шаг read_csv.

Спасибо!

1 Ответ

0 голосов
/ 09 ноября 2018

Здесь вы можете сделать это в 3 шага:

# put in the label column into id where text is null, and strip out the #. 
# The rest will be NaN
df['id'] = df.loc[df['text'].isnull(),'label'].str.strip('#')

# forward fill in ID
df['id'].ffill(inplace=True)

# Remove the columns where text is null
df.dropna(subset=['text'], inplace=True)

>>> df
         label          text        id
1        INTRO  Some text...  24293578
2      METHODS  Some text...  24293578
3      METHODS  Some text...  24293578
4      METHODS  Some text...  24293578
5      RESULTS  Some text...  24293578
7   BACKGROUND  Some text...  24854809
8        INTRO  Some text...  24854809
9      METHODS  Some text...  24854809
10     METHODS  Some text...  24854809
11     RESULTS  Some text...  24854809
13  BACKGROUND  Some text...  25165090
14     METHODS  Some text...  25165090
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...