2014-01-13 4 views
0

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

Итак, у меня есть dataframe с небольшим количеством строк (от 20 до нескольких сотен) и меньшим количеством столбцов. Я использовал read_table панды работать, чтобы получить в исходных данных в .txt формы, которая выглядит следующим образом:

[ID1, Gene1, Sequence1, Ratio1, Ratio2, Ratio3] 
[ID1, Gene1, Sequence2, Ratio1, Ratio2, Ratio3] 
[ID2, Gene2, Sequence3, Ratio1, Ratio2, Ratio3] 
[ID2, Gene3, Sequence4, Ratio1, Ratio2, Ratio3] 
[ID3, Gene3, Sequence5, Ratio1, Ratio2, Ratio3] 

... вместе с целой кучей несущественных столбцов.

Что я хочу сделать, это выбрать все коэффициенты из каждой последовательности и выполнить некоторые вычисления и статистику по ним (все 3 отношения для каждой последовательности, то есть). Я пробовал

df.groupby('Sequence') 
for col in df: 
    do something/print(col)/print(col[0]) 

... но это только меня смущает. Если я передаю print (col), я получаю какую-то конструкцию df, тогда как если я пройду печать (col [0]), я получаю только последовательности. Насколько я могу видеть в конструкции, у меня все равно должны быть все остальные столбцы и их данные, так как groupby() не удаляет какие-либо данные, он просто группирует их по некоторому столбцу ввода. Что я делаю не так?

Хотя я еще не получил этого еще, из-за проблем, описанных выше, я также хочу, чтобы мой скрипт мог выбирать все коэффициенты для каждого идентификатора и выполнять те же вычисления на них, но на этот раз каждое соотношение (т. е. Ratio1 для всех строк ID1, то же самое для Ratio2 и т. д.). И, наконец, делайте то же самое для каждого гена.

EDIT:

Так, скажем, я хочу, чтобы выполнить этот расчет на каждом соотношении в ряду, а затем взять медиану из трех полученных значений:

df[Value1] = spike[data['ID']]/float(data['Ratio 1]) * (10**-12) * (6.022*10**23)/(1*10**6) 
df[Value2] = spike[data['ID']]/float(data['Ratio 2]) * (10**-12) * (6.022*10**23)/(1*10**6) 
df[Value3] = spike[data['ID']]/float(data['Ratio 3]) * (10**-12) * (6.022*10**23)/(1*10**6) 

... где Спайк словарь, а ключи - это идентификаторы. Игнорируя часть dict, я могу делать вычисления (спасибо!), Но как мне получить доступ к словарю, используя идентификаторы dataframe? С приведенным выше кодом я просто получаю сообщение об ошибке «Unhashable type: Series».

Вот некоторые реальные данные:

ID Gene Sequence Ratio1 Ratio2 Ratio3 
1 KRAS SFEDXXYR 15.822 14.119 14.488 
2 KRAS VEDAXXXLVR 9.8455 8.9279 16.911 
3 ELK4 IEXXXCESLNK 15.745 7.9122 9.5966 
3 ELK4 IEGXXXSLNKR 1.177 NaN  12.073 
+0

Можете ли вы дать небольшой, но с реальными данными, образец набора данных? Поэтому мы можем попробовать свои функции. – joris

ответ

1
  1. df.groupby() не изменяет/группу df на месте. Таким образом, вы должны назначить результат новой переменной для дальнейшего ее использования. Например. :

    grouped = df.groupby('Sequence') 
    

    BTW, в примере данных вы даете, все данные в столбце Sequence являются уникальными, поэтому группировка на этой колонке будет не слишком много.
    Кроме того, вам обычно не нужно «перебирать df», как вы это делаете. Чтобы применить функцию ко всем группам, вы можете сделать это непосредственно по результату groupby, например df.groupby().apply(..) или df.groupby().aggregate(..).

  2. Можете ли вы дать более конкретный пример того, какую функцию вы хотите применить к отношениям?

    Для расчета медианы три соотношения для каждой последовательности (каждая строка), вы можете сделать:

    df[['Ratio1', 'Ratio2', 'Ratio3']].median(axis=1) 
    

    axis=1 означает, что вы не хотите взять медиану одной колонки (по рядам), но для каждой строки (по столбцам)

Другой нелогич-, вычислить медиану всех Ratio1-х для каждого идентификатора, вы можете сделать:

df.groupby('ID')['Ratio1'].median() 

Здесь вы группируете ID, выберите столбец Ratio1 и вычислите медианное значение для каждой группы.


UPDATE: вы, вероятно, следует разделить вопросы на отдельные из них, но в качестве ответа на ваш новый вопрос:

data['ID'] даст вам ID колонку, так что вы не можете использовать его в качестве ключа. Вы хотите одно конкретное значение этого столбца. Чтобы применить функцию на каждой строке dataframe, вы можете использовать apply:

def my_func(row): 
    return spike[row['ID']]/float(row['Ratio 1']) * (10**-12) * (6.022*10**23)/(1*10**6) 

df['Value1'] = df.apply(my_func, axis=1) 
+0

1. Извините, я был неясен. У меня есть новый df, который я перебираю, как код выше. (df ​​= df.groupby ('Sequence') 2. Я в основном хочу медиану трех отношений для каждой последовательности и некоторые другие статистические вычисления (std, cv и т. д.). На более поздних этапах я хочу, чтобы медианы для все Ratio1 ID1, медианы Ratio2, Ratio3, а затем еще одна медиана медианов из коэффициентов. – Sajber

+1

Его действительно полезно прочитать эти документы, чтобы увидеть примеры этих типов групповых операций: http://pandas.pydata.org/ pandas-docs/dev/groupby.html – Jeff

+0

О, очень круто, Джорис! Что делать, если я хотел выполнить какой-то другой, нестандартный расчет для каждого отношения, а THEN вычислить медиану полученных трех значений? Что, если некоторые из этих для вычисления требуется значение из отдельного словаря, где идентификатор к соответствующим трем отношениям должен быть введен как ключ? – Sajber

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