【问题标题】:Pandas: selecting multiple columns from one row熊猫:从一行中选择多列
【发布时间】:2014-01-13 10:36:29
【问题描述】:

我有一个脚本可以为我做事,但效率很低。我向代码审查者寻求一些帮助,并被告知尝试使用 Pandas。这就是我所做的,但我很难理解它是如何工作的。我已尝试阅读此处的文档和其他问题,但找不到任何答案。

所以,我有一个包含少量行(20 到几百)和少量列的数据框。我使用 read_table pandas 函数来获取 .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 构造,而如果我通过 print(col[0]),我只会得到序列。据我在构造中看到的,我应该仍然拥有所有其他列及其数据,因为 groupby() 不会删除任何数据,它只是按某个输入列对它进行分组。我做错了什么?

虽然我还没有走到那一步,但由于上述问题,我还希望我的脚本能够选择每个 ID 的所有比率并对它们执行相同的计算,但这次是每个比率本身(即 ID1 的所有行的 Ratio1,Ratio2 相同,等等)。最后,对每个基因做同样的事情。

编辑:

所以,假设我想对行中的每个比率执行此计算,然后取三个结果值的中位数:

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)

... 其中spike 是字典,键是ID。忽略 dict 部分,我可以进行计算(谢谢!),但是如何使用数据框 ID 访问字典?使用上面的代码,我只得到一个“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

【问题讨论】:

  • 你能给出一个小但有真实数据的样本数据集吗?所以我们可以试试这些功能。

标签: python pandas


【解决方案1】:
  1. df.groupby() 不会修改/组合df。因此,您必须将结果分配给一个新变量以进一步使用它。例如。 :

    grouped = df.groupby('Sequence')
    

    顺便说一句,在您提供的示例数据中,Sequence 列中的所有数据都是唯一的,因此对该列进行分组不会有太大作用。
    此外,您通常不需要像在此处那样“迭代 df”。要将函数应用于所有组,您可以直接在 groupby 结果上执行此操作,例如 df.groupby().apply(..) 或 df.groupby().aggregate(..)。

  2. 你能举一个更具体的例子来说明你想对比率应用什么样的函数?

    要计算每个序列(每一行)的三个比率的中位数,您可以:

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

    axis=1 表示您不想取一列(在行上)的中位数,而是对每一行(在列上)取中位数

另一个例子,要计算每个 ID 的所有 Ratio1 的中位数,你可以这样做:

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

在这里您按ID 分组,选择列Ratio1 并计算每个组的中值。


更新:您可能应该将问题分成单独的问题,但作为对新问题的回答:

data['ID'] 将为您提供ID 列,因此您不能将其用作键。您需要该列的一个特定值。要对数据框的每一行应用函数,可以使用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)

【讨论】:

  • 1.对不起,我不清楚。如上面的代码,我有一个新的 df 进行迭代。 (df = df.groupby('Sequence') 2. 我基本上想要每个序列的三个比率的中位数,以及其他一些统计计算(std、cv 等)。在后期我想要所有的中位数ID1 的 Ratio1,Ratio2 的中位数,Ratio3,然后是比率中位数的另一个中位数。
  • 阅读这些文档以查看这些类型的 groupby 操作的示例非常有帮助:pandas.pydata.org/pandas-docs/dev/groupby.html
  • 哦,太酷了,乔里斯!如果我想对每个比率执行其他一些非标准计算,然后计算结果三个值的中位数怎么办?如果某些计算需要一个单独的字典中的值,其中对应的三个比率的 ID 必须作为键输入怎么办?
  • 也许只是计算并将其分配给新列,然后取中位数。但是,如果您还有其他问题,请尝试给出一个非常具体的案例(所以不是“某些功能”,这完全取决于哪种功能),以及一些您已经尝试过或可以重现问题的代码。浏览 Jeff 链接到的文档会很有帮助,只是为了学习概念。
  • 函数解决了,非常感谢!正如你所说,我也会尝试拆分未来的问题^^
猜你喜欢
  • 2018-06-25
  • 1970-01-01
  • 2021-12-21
  • 1970-01-01
  • 2016-07-24
  • 2018-08-05
  • 2021-04-03
相关资源
最近更新 更多