2013-06-30 2 views
0

======================= ОБНОВЛЕНИЕ # 2 ======== ====================================Выбор записей данных данных Pandas на основе содержимого поля серии

Какой день. Я очень медленно продвигаюсь вперед. Но в то время как PANDAS очень быстрый и мощный, он имеет крутую кривую обучения и не очень хорошие примеры (по крайней мере, для того, что я пытаюсь сделать).

последняя проблема с конкретной строки:

catfile = infile[infile['dtu_topic_split'].map(lambda x: any(targetcat in x))] 

, который работает в IPyNotebook, но не под Ubuntu и питона 2,7

здесь ошибка в Ubuntu:

Traceback (most recent call last): 
     File "scikit2.py", line 27, in <module> 
     catfile = infile[infile['dtu_topic_split'].map(lambda x: any(targetcat in x))] 
     File "/usr/local/lib/python2.7/dist-packages/pandas-0.11.0-py2.7-linux-x86_64.egg/pandas/core/series.py", line 2408, in map 
     mapped = map_f(values, arg) 
     File "inference.pyx", line 861, in pandas.lib.map_infer (pandas/lib.c:41822) 
     File "scikit2.py", line 27, in <lambda> 
     catfile = infile[infile['dtu_topic_split'].map(lambda x: any(targetcat in x))] 
    TypeError: 'bool' object is not iterable 

и рабочий код + результаты в iPyNotebook

targetcat = 'Financial Services Industries' 
#targetcat = 'Payroll & Employment Tax' 
criterion = foo[foo['dtu_topic_split'].map(lambda x: any(targetcat in x))] 
print criterion[['dtu_docid','dtu_topic_split']][:10] 



    dtu_docid         dtu_topic_split 
9 2010-0185     [Financial Services Industries] 
17 2010-0152 [Financial Services Industries, International ... 
46 2012-1421 [Financial Services Industries, Payroll & Empl... 
49 2012-1413 [Financial Services Industries, Payroll & Empl... 
66 2012-1370 [Energy Taxation, Financial Services Industrie... 
94 2009-1786     [Financial Services Industries] 
144 2012-1170  [Financial Services Industries, Real Estate] 
163 2012-1101  [Financial Services Industries, Real Estate] 
170 2009-1386     [Financial Services Industries] 
249 2012-0754 [Expatriate Taxation, Financial Services Indus... 

Вот версия питона для iPYNotebook

print sys.version 
2.7.4 (default, Apr 19 2013, 18:28:01) 
[GCC 4.7.3] 

и от Ubuntu:

>>> import sys 
>>> print sys.version 
2.7.4 (default, Apr 19 2013, 18:28:01) 
[GCC 4.7.3] 
>>> 

Нужна помощь. Я уверен, что я мог бы сделать это с помощью этой настройки данных и ухода, если бы использовал традиционную обработку. Все еще пытаясь PANDAS, но это жесткие санки, и самая грустная часть - я даже не уверен, почему материал, который я получил, работает. Эти типы ошибок порождают разочарование

============================== ОБНОВЛЕНИЕ # 1 ============= ================================

Использование информации в 1-м ответе (спасибо tshauck) один из способов достижения этого вопроса:

targetcat = 'International Taxation' 
criterion = foo[foo['dtu_topic_split'].map(lambda x: any(targetcat in x))] 

Это дает список строк, где targetcat в серии dataframe.dtu_topic_split. Учитывая, что я новичок в панде, это лучший способ справиться. Я намерен создать отдельные учебные модули для каждой из 30-50 категорий. Я не уверен, должен ли я перебирать приблизительно 100 тыс. Записей в более традиционном стиле python или использовать технику pandas. Снова будут приветствованы любые альтернативы или рекомендации.


Я новичок в Pandas и изо всех сил стараюсь научиться пользоваться мощными возможностями. Вчера я опубликовал стратегию для решения этой проблемы путем создания отдельного блока данных. Прочитав больше, я не уверен, что он самый эффективный. Я пробовал несколько методов для выбора конкретных строк, формирующих datafarame на основе существования определенного значения в поле серии кадра данных. Ниже приведен образец данных и моих попыток.

print foo[['dtu_docid','dtu_topic_split']] 

/home/davidwaldrop/Dropbox/Miscelaneous/E&Y M&C Project/scikit training 
    dtu_docid         dtu_topic_split 
0 2012-1553   [Energy Taxation, State & Local Taxation] 
1 2012-1552   [Legislation & Policy, Financial Services] 
2 2010-0227   [Quantitative Economics and Statistics] 
3 2010-0215      [International Taxation, Asia] 
4 2012-1529 [Ernst & Young Newsletters, This Week in Tax R... 

И вот что я работаю сейчас, но безрезультатно:

targetcat = ['International Taxation'] 

criterion = foo['dtu_topic_split'].map(lambda x: x == targetcat) 

print foo[criterion] 

Empty DataFrame 
Columns: [id, dtu_docid, dtu_topic, dtu_content, dtu_topic_split] 
Index: [] 

То, что я хочу является dataframe, содержащие записи, где «Международное налогообложение» является в серии хранящейся в поле dtu_topic_split или в приведенном выше примере запись в foo [3] с значением dtu_topic_split [International Taxation, Asia].

Как я уже говорил, я действительно пытаюсь узнать Панды и думаю, что это очень мощный. Как новичок очень трудно не только найти способ делать то, что я хочу, но и наилучшим образом вместе с рациональным. Мой инстинкт подсказывает мне, что это лучше всего сделать с индексированием, но я еще не добрался до этой функции. Любое понимание наиболее ценится.

ответ

0

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

Если предположить, что это дело что-то вроде следующего может работать:

targetcat = ['International Taxation'] 

criterion = foo['dtu_topic_split'].map(lambda possiblecat: \ 
    any([t in p for t in targetcat for p in possiblecat])) 

Я не проверял, но я думаю, что это возвращает истину, если какой-либо категории в targetcat содержится в любой подстроке категории в possiblecat.

+0

Спасибо за идею. Я пытался, но он возвращает True для всего. Я проанализирую раздел карты заявления, так как это часть, которая больше всего путает понимать эту конкретную проблему и Панды в целом. Еще раз спасибо. вот что я получил в качестве результатов:. критерия = Foo [ «dtu_topic_split»] карты (лямбда possiblecat: любой ([т в р для т в targetcat для р в possiblecat])) критерия печати печати Foo [критерий ] 0 Правда 1 Правда 2 Правда 3 Правда 4 Правда Имя: dtu_topic_split, DTYPE: BOOL dtu_docid идентификатор – david

2

Надеюсь, я хорошо понимаю ваш конкретный случай использования, чтобы обеспечить достойный ответ.

Учитывая некоторые данные:

data = """ 
dtu_docid|dtu_topic_split 
9|2010-0185|['Financial Services Industries'] 
17|2010-0152|['Financial Services Industries', 'International'] 
46|2012-1421|['Financial Services Industries', 'Payroll & Employment Tax'] 
49|2012-1413|['Financial Services Industries', 'Payroll & Employment Tax'] 
66|2012-1370|['Energy Taxation', 'Financial Services Industries'] 
94|2009-1786|['Financial Services Industries'] 
144|2012-1170|['Financial Services Industries', 'Real Estate'] 
163|2012-1101|['Financial Services Industries', 'Real Estate'] 
170|2009-1386|['Financial Services Industries'] 
249|2012-0754|['Expatriate Taxation', 'Financial Services Industries'] 
""".split('\n') 

И с этим вопросом в виде:

«То, что я хочу является dataframe, содержащие записи, где„Международный налогообложение“находится в серии, хранящейся в поле dtu_topic_split»

Вы можете получить его в DataFrame

rows = [row for row in data if len(row) > 0] 

cleaned = [] 
for i, row in enumerate(rows): 
    row = row.split('|') 
    if i == 0: 
     headers = row 
    else: 
     row = row[1:] # get rid of the index 
     row[1] = eval(row[1]) 
     cleaned.append(row) 

df = pd.DataFrame(cleaned, columns=headers) 

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

print df 
    dtu_docid         dtu_topic_split 
0 2010-0185     [Financial Services Industries] 
1 2010-0152  [Financial Services Industries, International] 
2 2012-1421 [Financial Services Industries, Payroll & Empl... 
3 2012-1413 [Financial Services Industries, Payroll & Empl... 
4 2012-1370 [Energy Taxation, Financial Services Industries] 
5 2009-1786     [Financial Services Industries] 
6 2012-1170  [Financial Services Industries, Real Estate] 
7 2012-1101  [Financial Services Industries, Real Estate] 
8 2009-1386     [Financial Services Industries] 
9 2012-0754 [Expatriate Taxation, Financial Services Indus... 

Теперь у вас есть этот неудобный dtu_topic_split столбец это список питона. Это немного сложно справиться.

Чтобы выбрать строки с одним интересующим вас товаром, вы можете использовать apply a lambda. Например:

print df.dtu_topic_split.apply(lambda x: 'Energy Taxation' in x) 

Это даст вам булевскую серию.

0 False 
1 False 
2 False 
3 False 
4  True 
5 False 
6 False 
7 False 
8 False 
9 False 
Name: dtu_topic_split, dtype: bool 

И вы можете передать это df[...] через подзадачу.

energy = df[df.dtu_topic_split.apply(lambda x: 'Energy Taxation' in x)] 

print energy 
    dtu_docid         dtu_topic_split 
4 2012-1370 [Energy Taxation, Financial Services Industries] 

Другой путь, который мог бы работать лучше, чтобы получить данные в long format.

Возвращаясь к переменной cleaned (список списков), вы можете написать небольшую функцию, которая «стекирует» строки, содержащие более одной темы.

def make_long(cleaned): 
    lng = [] 
    for row in cleaned: 
     # row is a list of length 2 
     topics = row[1] # second item is the list of topics 
     dtu_docid = row[0] 
     for topic in topics: 
      lng.append([dtu_docid, topic]) 

    return lng 

В этом случае cleaned был длиной 10 рядов. Когда вы вызываете make_long, вы получаете 17 строк, так как любая строка, имеющая более 1 темы, появляется более одного раза.

make_long(cleaned) 
Out[208]: 
[['2010-0185', 'Financial Services Industries'], 
['2010-0152', 'Financial Services Industries'], 
['2010-0152', 'International'], 
['2012-1421', 'Financial Services Industries'], 
['2012-1421', 'Payroll & Employment Tax'], 
['2012-1413', 'Financial Services Industries'], 
['2012-1413', 'Payroll & Employment Tax'], 
['2012-1370', 'Energy Taxation'], 
['2012-1370', 'Financial Services Industries'], 
['2009-1786', 'Financial Services Industries'], 
['2012-1170', 'Financial Services Industries'], 
['2012-1170', 'Real Estate'], 
['2012-1101', 'Financial Services Industries'], 
['2012-1101', 'Real Estate'], 
['2009-1386', 'Financial Services Industries'], 
['2012-0754', 'Expatriate Taxation'], 
['2012-0754', 'Financial Services Industries']] 

Тогда вы можете вставить это в dataframe, и вы должны быть в бизнесе.

lng = pd.DataFrame(make_long(cleaned), 
    columns=['dtu_docid', 'dtu_topic_split']) 

print lng 
    dtu_docid    dtu_topic_split 
0 2010-0185 Financial Services Industries 
1 2010-0152 Financial Services Industries 
2 2010-0152     International 
3 2012-1421 Financial Services Industries 
4 2012-1421  Payroll & Employment Tax 
5 2012-1413 Financial Services Industries 
6 2012-1413  Payroll & Employment Tax 
7 2012-1370    Energy Taxation 
8 2012-1370 Financial Services Industries 
9 2009-1786 Financial Services Industries 
10 2012-1170 Financial Services Industries 
11 2012-1170     Real Estate 
12 2012-1101 Financial Services Industries 
13 2012-1101     Real Estate 
14 2009-1386 Financial Services Industries 
15 2012-0754   Expatriate Taxation 
16 2012-0754 Financial Services Industries 

Таким образом, вы можете выбрать строки по одной или нескольким темам, в то время, используя метод isin на pd.Series объекта.

selected = ['Financial Services Industries', 'Real Estate'] 
print lng[lng.dtu_topic_split.isin(selected)] 

    dtu_docid    dtu_topic_split 
0 2010-0185 Financial Services Industries 
1 2010-0152 Financial Services Industries 
3 2012-1421 Financial Services Industries 
5 2012-1413 Financial Services Industries 
8 2012-1370 Financial Services Industries 
9 2009-1786 Financial Services Industries 
10 2012-1170 Financial Services Industries 
11 2012-1170     Real Estate 
12 2012-1101 Financial Services Industries 
13 2012-1101     Real Estate 
14 2009-1386 Financial Services Industries 
16 2012-0754 Financial Services Industries 

Надеюсь, что-то об этом полезно!