2016-11-04 4 views
0
Alabama[edit] 
Auburn (Auburn University)[1] 
Florence (University of North Alabama) 
Jacksonville (Jacksonville State University)[2] 
Alaska[edit] 
Fairbanks (University of Alaska Fairbanks)[2] 
Arizona[edit] 
Flagstaff (Northern Arizona University)[6] 
Tempe (Arizona State University) 
Tucson (University of Arizona) 

Это мой текст, мне нужно создать фрейм данных с 1 столбцом для имени состояния и еще один столбец для названия города, я знаю, как для удаления университетских имен. но как я могу сказать пандам, что при каждом изменении [edit] это новое состояние.read_table в pandas, как получить входной сигнал от текстового кадра

ожидается выход dataframe

Alabama Auburn 
Alabama Florence 
Alabama Jacksonville 
Alaska Fairbanks 
Arizona Flagstaff 
Arizona Tempe 
Arizona Tucson 

Я не уверен, если я могу использовать read_table, если я могу как? Я импортировал все в dataframe, но состояние и город находятся в одной колонке. Также я попробовал со списком, но проблема все та же.

мне нужно что-то, что работает, как если есть [править] в строке, то все значение после него и до следующего [править] строка состояния линий между

ответ

3

Может pandas может сделать но вы можете сделать это легко.

data = '''Alabama[edit] 
Auburn (Auburn University)[1] 
Florence (University of North Alabama) 
Jacksonville (Jacksonville State University)[2] 
Alaska[edit] 
Fairbanks (University of Alaska Fairbanks)[2] 
Arizona[edit] 
Flagstaff (Northern Arizona University)[6] 
Tempe (Arizona State University) 
Tucson (University of Arizona)''' 

# --- 

result = [] 

state = None 

for line in data.split('\n'): 

    if line.endswith('[edit]'): 
     # remember new state 
     state = line[:-6] # without `[edit]` 
    else: 
     # add state, city to result 
     city, rest = line.split(' ', 1) 
     result.append([state, city]) 

# --- display --- 

for state, city in result: 
    print(state, city) 

, если чтение из файла, то

result = [] 

state = None 

with open('your_file') as f: 
    for line in f: 
     line = line.strip() # remove '\n' 

     if line.endswith('[edit]'): 
      # remember new state 
      state = line[:-6] # without `[edit]` 
     else: 
      # add state, city to result 
      city, rest = line.split(' ', 1) 
      result.append([state, city]) 

# --- display --- 

for state, city in result: 
    print(state, city) 

Теперь вы можете использовать result для создания DataFrame.

+0

спасибо, работает отлично. только 'city, rest = line.split ('', 1) 'не работает для чего-то вроде Нью-Йорка, но его легко исправить – lucarlig

+0

возможно' split ("(") 'должен работать. – furas

+0

да я уже исправил его – lucarlig

2

Использование панд, вы можете сделать следующее:

import pandas as pd 
df = pd.read_table('data', sep='\n', header=None, names=['town']) 
df['is_state'] = df['town'].str.contains(r'\[edit\]') 
df['groupno'] = df['is_state'].cumsum() 
df['index'] = df.groupby('groupno').cumcount() 
df['state'] = df.groupby('groupno')['town'].transform('first') 
df['state'] = df['state'].str.replace(r'\[edit\]', '') 
df['town'] = df['town'].str.replace(r' \(.+$', '') 
df = df.loc[~df['is_state']] 
df = df[['state','town']] 

, который дает

 state   town 
1 Alabama  Auburn 
2 Alabama  Florence 
3 Alabama Jacksonville 
5 Alaska  Fairbanks 
7 Arizona  Flagstaff 
8 Arizona   Tempe 
9 Arizona  Tucson 

Вот расстройство того, что делает код. После загрузки текстового файла в DataFrame используйте str.contains, чтобы идентифицировать строки, которые являются состояниями. Используйте cumsum взять накопленную сумму True/False значения, где правда трактуются как 1 и Ложной как 0.

df = pd.read_table('data', sep='\n', header=None, names=['town']) 
df['is_state'] = df['town'].str.contains(r'\[edit\]') 
df['groupno'] = df['is_state'].cumsum() 
#            town is_state groupno 
# 0         Alabama[edit]  True  1 
# 1     Auburn (Auburn University)[1] False  1 
# 2   Florence (University of North Alabama) False  1 
# 3 Jacksonville (Jacksonville State University)[2] False  1 
# 4          Alaska[edit]  True  2 
# 5 Fairbanks (University of Alaska Fairbanks)[2] False  2 
# 6         Arizona[edit]  True  3 
# 7  Flagstaff (Northern Arizona University)[6] False  3 
# 8     Tempe (Arizona State University) False  3 
# 9     Tucson (University of Arizona) False  3 

Теперь для каждого groupno числа, мы можем присвоить уникальное число для каждой строки в группе :

df['index'] = df.groupby('groupno').cumcount() 
#            town is_state groupno index 
# 0         Alabama[edit]  True  1  0 
# 1     Auburn (Auburn University)[1] False  1  1 
# 2   Florence (University of North Alabama) False  1  2 
# 3 Jacksonville (Jacksonville State University)[2] False  1  3 
# 4          Alaska[edit]  True  2  0 
# 5 Fairbanks (University of Alaska Fairbanks)[2] False  2  1 
# 6         Arizona[edit]  True  3  0 
# 7  Flagstaff (Northern Arizona University)[6] False  3  1 
# 8     Tempe (Arizona State University) False  3  2 
# 9     Tucson (University of Arizona) False  3  3 

Снова для каждого groupno числа, мы можем найти состояние, выбрав первый город в каждой группе:

df['state'] = df.groupby('groupno')['town'].transform('first') 
#            town is_state groupno index   state 
# 0         Alabama[edit]  True  1  0 Alabama[edit] 
# 1     Auburn (Auburn University)[1] False  1  1 Alabama[edit] 
# 2   Florence (University of North Alabama) False  1  2 Alabama[edit] 
# 3 Jacksonville (Jacksonville State University)[2] False  1  3 Alabama[edit] 
# 4          Alaska[edit]  True  2  0 Alaska[edit] 
# 5 Fairbanks (University of Alaska Fairbanks)[2] False  2  1 Alaska[edit] 
# 6         Arizona[edit]  True  3  0 Arizona[edit] 
# 7  Flagstaff (Northern Arizona University)[6] False  3  1 Arizona[edit] 
# 8     Tempe (Arizona State University) False  3  2 Arizona[edit] 
# 9     Tucson (University of Arizona) False  3  3 Arizona[edit] 

мы в основном час ave желаемый DataFrame; все, что осталось, - это префикс результата. Мы можем удалить [edit] из state с и все после первой скобки от town с помощью str.replace:

df['state'] = df['state'].str.replace(r'\[edit\]', '') 
df['town'] = df['town'].str.replace(r' \(.+$', '') 

Удалите строки, где town фактически состояние:

df = df.loc[~df['is_state']] 

И, наконец, , сохраните только нужные столбцы:

df = df[['state','town']] 
+0

это здорово, но быстрее затем цикл for и список? – lucarlig

+0

Для достаточно большого текстового файла использование векторных функций на основе столбцов Pandas должно быть быстрее, чем использование цикла Python. Для небольших файлов цикл Python может быть быстрее. Для очень больших текстовых файлов, код Pandas должен быть намного быстрее, чем эквивалентный код, используя цикл Python. – unutbu

+0

@lucarlig: после некоторого бенчмаркинга, кажется, цикл Python быстрее для любого файла размером в разумный размер (в конце концов, не так много штатов и городов.) Так что действительно, ответ фураса - более практичное решение. – unutbu

 Смежные вопросы

  • Нет связанных вопросов^_^