【问题标题】:Calculating sum of a combination of columns in pandas, row-wise, with output file with the name of said combination计算pandas中列组合的总和,按行计算,输出文件具有所述组合的名称
【发布时间】:2018-06-07 12:32:48
【问题描述】:

我正在寻找一种方法来为数据框中列的特定数据组合生成 csv 文件。

我的数据看起来像这样(除了 200 多行)

+-------------------------------+-----+----------+---------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+---------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
|            Species            | OGT |  Domain  |       A       |      C       |      D       |      E       |      F       |      G       |      H       |      I       |      K       |       L       |      M       |      N       |      P       |      Q       |      R       |      S       |      T       |      V       |      W       |      Y       |
+-------------------------------+-----+----------+---------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+---------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
| Aeropyrum pernix              |  95 | Archaea  |  9.7659115711 | 0.6720465616 | 4.3895390781 | 7.6501943794 | 2.9344881615 | 8.8666657183 | 1.5011817208 | 5.6901432494 | 4.1428307243 | 11.0604191603 |   2.21143353 | 1.9387130928 | 5.1038552753 | 1.6855017182 | 7.7664358772 |  6.266067034 | 4.2052190807 | 9.2692433532 |  1.318690698 | 3.5614200159 |
| Argobacterium fabrum          |  26 | Bacteria | 11.5698896021 | 0.7985475923 | 5.5884500155 | 5.8165463343 | 4.0512504104 | 8.2643271309 | 2.0116736244 | 5.7962804605 | 3.8931525401 |  9.9250463349 | 2.5980609708 | 2.9846761128 | 4.7828063605 | 3.1262365491 | 6.5684282943 | 5.9454781844 | 5.3740045968 | 7.3382308193 | 1.2519739683 | 2.3149400984 |
| Anaeromyxobacter dehalogenans |  27 | Bacteria | 16.0337898849 | 0.8860252895 | 5.1368827707 | 6.1864992608 | 2.9730203513 | 9.3167603253 | 1.9360386851 |  2.940143349 | 2.3473650439 |  10.898494736 | 1.6343905351 | 1.5247123262 | 6.3580285706 | 2.4715303021 | 9.2639057482 | 4.1890063803 | 4.3992339725 | 8.3885969061 | 1.2890166336 | 1.8265589289 |
| Aquifex aeolicus              |  85 | Bacteria |  5.8730327277 |  0.795341216 | 4.3287799008 | 9.6746388172 | 5.1386954322 | 6.7148035486 | 1.5438364179 | 7.3358775924 | 9.4641440609 | 10.5736658776 | 1.9263080969 | 3.6183861236 | 4.0518679067 | 2.0493569604 | 4.9229955632 | 4.7976564501 | 4.2005259246 | 7.9169763709 | 0.9292167138 | 4.1438942987 |
| Archaeoglobus fulgidus        |  83 | Archaea  |  7.8742687687 | 1.1695110027 | 4.9165979364 | 8.9548767369 |  4.568636662 | 7.2640358917 | 1.4998752909 | 7.2472039919 | 6.8957233203 |  9.4826333048 | 2.6014466253 |  3.206476915 | 3.8419576418 | 1.7789787933 | 5.7572748236 | 5.4763351139 | 4.1490633048 | 8.6330814159 | 1.0325605451 | 3.6494619148 |
+-------------------------------+-----+----------+---------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+---------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+

我想做的是找到一种方法来生成带有物种、OGT 的 csv,然后结合其他一些列,比如 A、C、E 和 G 以及这些特定列的百分比总和价值观。

所以输出看起来像这样:(这些总和只是组成)

ACEG.csv

             Species              OGT   Sum of percentage  
 ------------------------------- ----- ------------------- 
  Aeropyrum pernix                 95             23.4353  
  Anaeromyxobacter dehalogenans    26             20.3232  
  Argobacterium fabrum             27             14.2312  
  Aquifex aeolicus                 85             15.0403  
  Archaeoglobus fulgidus           83             34.0532  

这样做的目的是让我可以为每列 (A-Y) 的 1000 万个组合中的每一个执行此操作,但我认为这是一个简单的 for 循环。我最初试图在 R 中实现这一点,但经过反思,在 python 中使用 pandas 可能是更好的选择。

【问题讨论】:

  • 你能解释一下你所说的百分比总和是什么意思吗?
  • 只需将它们加在一起!
  • 虽然有很多方法可以满足您的要求,但我认为实际上需要考虑所有组合的应用程序很少。如果您说出您打算如何处理这些数据,您可能会得到更好的建议。
  • 我计划关联这些氨基酸百分比的不同组合,并查看哪种 AA 组合是原核生物最佳生长温度的最佳指标,同时也考虑其他信号。十年前进行了一项早期研究,但我认为他们没有考虑其他因素!
  • 所以你想选择一个最大化某个目标的组合?如果你能以一种外行可以理解的方式在数学上定义这个目标,我敢打赌你会得到更有效的解决方案。

标签: python pandas dataframe combinatorics


【解决方案1】:

这样的?

def subset_to_csv(cols):
    df['Sum of percentage'] = your_data[list(cols)].sum(axis=1)
    df.to_csv(cols + '.csv')

df = your_data[['Species', 'OGT']]

for c in your_list_of_combinations:
    subset_to_csv(c)

其中cols 是一个字符串,其中包含您要子集化的列,例如:'ABC'

【讨论】:

    【解决方案2】:

    您可以尝试以下方法:

    from itertools import product
    from string import ascii_uppercase
    import pandas as pd
    
    combinations = [''.join(i) for i in product(ascii_uppercase, repeat = 4)]
    
    for combination in combinations:
        new_df = df[['Species', 'OGT']]
        new_df['Sum of percentage'] = df[list(combination)]
        new_df.to_csv(combination + '.csv')
    

    ====

    按照 Yakym Pirozhenko 的评论进行编辑,combinations 应该使用 itertools.combinations 以避免重复,例如 'AAAA'

    combinations = [''.join(i) for i in itertools.combinations(ascii_uppercase, r = 4)]
    

    【讨论】:

    • 与其他答案的评论相同:由于 OP 计划运行数百万次,您可能需要预先分配一个 df 并覆盖 df['Sum of percent']。比每次复制 Species 和 OGT 效率略高。
    • 另外,combinations 可以是生成器。
    • 您忘记对给定组合的列求和,您的代码现在正尝试将 df 的几列的值分配到 new_df 的单个列中
    • 这很好,我正在使用combinations 编辑我的答案。
    • 另外,在您的 combinations 中,您假设所有字母都不是大小写(例如:没有 U、J 或 Z 列)
    【解决方案3】:

    不是原始问题的答案,但考虑到讨论,这可能很有用。

    目标是找到一个列组合,使得列总和与OGT 具有最大相关性。这很容易,因为协方差是双线性的:

    • cov(OGT, A+B) = cov(OGT, A) + cov(OGT, B)

    我依赖于两个简化的假设:

    1. 因素 A、B、C 等是独立的。
    2. 物种的权重相同。
    3. 每个因子的方差为1

    想法:

    1. 将所有列标准化以具有单位方差(即假设 3)。
    2. 计算 OGT 与每列的协方差。
    3. 按协方差递减的顺序对因子 A、B、C 进行排序。最佳组合将作为这种安排的前缀出现。
    4. 我们应该选择哪个前缀?标准差之和最大的那个。由于步骤 1 中的归一化,对于大小为 n 的前缀,每个前缀之和的每个标准差只是 sqrt(n)。仍然需要在序列中找到最大索引,这很容易。

    这可能比检查所有可能的组合要快一点。


    import pandas as pd
    import numpy as np
    
    # set up fake data
    import string
    
    df = pd.DataFrame(np.random.rand(3, 26), columns=list(string.ascii_uppercase))
    
    df["species"] = ["dog", "cat", "human"]
    df["OGT"] = np.random.randint(0, 100, 3)
    df = df.set_index("species")
    
    # actual work
    alpha_cols = list(string.ascii_uppercase)
    # normalize standard deviations of each column
    df = df[alpha_cols + ["OGT"]].div(df.std(0), axis=1)
    # compute correlations (= covariances) of OGT with each column
    corrs = df.corrwith(df.OGT).sort_values(ascending=False)
    del corrs["OGT"]
    
    # sort covariances in order from the greatest to the smallest
    # compute cumulative sums
    # divide by standard deviation of a group (i.e. sqrt(n) at index n-1)
    cutoff = (corrs.cumsum() / np.sqrt(np.arange(corrs.shape[0]) + 1)).idxmax()
    answer = sorted(corrs.loc[:cutoff].index.values)
    print(answer)
    
    # e.g.
    # ['B', 'I', 'K', 'O', 'Q', 'S', 'U', 'V', 'Y']
    

    【讨论】:

    • 这看起来对下一步非常有用,谢谢!
    猜你喜欢
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    • 2016-03-22
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 1970-01-01
    • 2019-10-11
    相关资源
    最近更新 更多