2016-01-14 1 views
0

Я бы хотел заменить длинную строку в моей кадре данных гораздо короче. У меня есть короткий словарь замены, который я хочу сделать.Как я могу заменить различные длинные строки для более коротких строк на протяжении всего моего фреймворка?

import pandas as pd 
from StringIO import StringIO 

replacement_dict = { 
    "substring1": "substring1", 
    "substring2": "substring2", 
    "a short substring": "substring3", 
} 

exampledata = StringIO("""id;Long String 
1;This is a long substring1 of text that has lots of words 
2;This is substring2 and also contains more text than needed 
3;This is a long substring1 of text that has lots of words 
4;This is substring2 and also contains more text than needed 
5;This is substring2 and also contains more text than needed 
6;This is substring2 and also contains more text than needed 
7;Within this string is a short substring that is unique 
8;This is a long substring1 of text that has lots of words 
9;Within this string is a short substring that is unique 
10;Within this string is a short substring that is unique 
""") 

df = pd.read_csv(exampledata, sep=";") 
print df 

for s in replacement_dict.keys(): 
    if df['Long String'].str.contains(s): 
     df['Long String'] = replacement_dict[df['Long String'].str.contains(s)] 

Ожидаемый dataframe будет выглядеть следующим образом:

id Long String 
0 1 substring1 
1 2 substring2 
2 3 substring1 
3 4 substring2 
4 5 substring2 
5 6 substring2 
6 7 substring3 
7 8 substring1 
8 9 substring3 
9 10 substring3 

Когда я запускаю код выше, я получаю эту ошибку:

Traceback (most recent call last): 
    File "test.py", line 27, in <module> 
    if df['Long String'].str.contains(s): 
    File "h:\Anaconda\lib\site-packages\pandas\core\generic.py", line 731, in __nonzero__.format(self.__class__.__name__)) 
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). 

Как я могу заменить различные длинные строки для более короткие строки на всей моей информационной карте?

ответ

1

Вы можете делать такие вещи с помощью .replace(). Однако вам придется немного изменить свой словарь, чтобы получить ожидаемый результат.

replacement_dict = { 
    ".*substring1.*": "substring1", 
    ".*substring2.*": "substring2", 
    ".*a short substring.*": "substring3", 
} 

Что я сделал, сделав ключи регулярной строкой. Он будет соответствовать всем до и после после подстроки, которую вы хотите сопоставить. Это будет важно через минуту.

Затем замените весь for цикл, со следующим:

df['Long String'] = df['Long String'].replace(replacement_dict, regex=True) 

.replace() может взять словарь, где ключи строки вы и соответствующие значения являются текст замены. Причина изменения ключей для захвата всего до и после вашей подстроки - это то, что теперь мы можем заменить все значение, а не просто небольшую строку.

Например, словарь без .* части будет преобразовать в dataframe так:

id          Long String 
0 1 This is a long substring1 of text that has lot... 
1 2 This is substring2 and also contains more text... 
2 3 This is a long substring1 of text that has lot... 
3 4 This is substring2 and also contains more text... 
4 5 This is substring2 and also contains more text... 
5 6 This is substring2 and also contains more text... 
6 7 Within this string is substring3 that is unique 
7 8 This is a long substring1 of text that has lot... 
8 9 Within this string is substring3 that is unique 
9 10 Within this string is substring3 that is unique 

Обратите внимание, что единственное изменение, которое вы действительно видите, со значениями «короткие подстроками», потому что вы на самом деле просто заменив «substring1» и «substring2» на себя.

Теперь, если мы добавим регулярные выражения символы назад, мы получаем следующее:

id Long String 
0 1 substring1 
1 2 substring2 
2 3 substring1 
3 4 substring2 
4 5 substring2 
5 6 substring2 
6 7 substring3 
7 8 substring1 
8 9 substring3 
9 10 substring3 
Смежные вопросы