【问题标题】:Python Pandas: Forming a matrix (2D array) from the values in a dataframe (ignoring NaN values)Python Pandas:从数据框中的值形成矩阵(二维数组)(忽略 NaN 值)
【发布时间】:2020-07-17 19:51:21
【问题描述】:

我有一个包含 12 列(药物类别)的数据框,其中相同的值(药物类别名称)可能会出现在不同的列中。

                             DRG01                     DRG02  ...   DRG11 DRG12
0          AMOXYCILLIN ORAL SOLIDS   AMOEBICIDES ORAL SOLIDS  ...   NaN   NaN
1                    VITAMIN DROPS                       NaN  ...   NaN   NaN
2          AMOXYCILLIN ORAL SOLIDS   ANTIHISTAMINES ORAL LIQ  ...   NaN   NaN
3          AMOEBICIDES ORAL LIQUID                       NaN  ...   NaN   NaN
...                            ...                       ...  ...   ...   ...
81531                          NaN                       NaN  ...   NaN   NaN
[81532 rows x 12 columns]

我的目标是创建一个矩阵(二维数组) - 行和列由唯一的药物类别名称组成(忽略/删除 NaN 值)。单元格的值将是这些药物类别名称连续出现的次数。本质上,我正在尝试实现以下目标:

                        AMOXYCILLIN ORAL SOLIDS  AMOEBICIDES ORAL SOLIDS  ANTIHISTAMINES ORALLIQ  VITAM..
AMOXYCILLIN ORAL SOLIDS      0                         1                       1                    0
AMOEBICIDES ORAL SOLIDS      1                         1                       0                    0
ANTIHISTAMINES ORAL LIQ      1                         0                       0                    0
VITAMIN DROPS                0                         0                       0                    1
.....
.....

【问题讨论】:

标签: python pandas dataframe matrix multidimensional-array


【解决方案1】:

像这样?

from collections import Counter
from collections import defaultdict as dd
import pandas as pd

connection_counter = dd(lambda: Counter()) # count for every drug the time it appears with every other drug
def to_counter(row): #send each row to the connection_counter and add a connection to each value in the row with all other drugs in row  
    for drug_name in row:
        connection_counter[drug_name].update(row)
        connection_counter[drug_name].pop(drug_name,None) # so it won't count an appearance with itself

df.apply(lambda x: to_counter(x), axis = 1)  #df is the table you have 

df1 = pd.DataFrame()  # the table you want

for drug_name in connection_counter:
    df1 = df1.append(pd.DataFrame(connection_counter[drug_name],index = [drug_name]))

【讨论】:

    【解决方案2】:

    使用 itertools.combinations 和一些 pandas 函数你可以做得很好:

    pairs_df = pd.DataFrame(df.apply(lambda x: pd.Series(map(sorted, combinations(x, 2))), axis=1).stack().to_list())
    # pairs_df has a row for every pair of drugs (in columns 0, 1).
    pairs_df["occurrences"] = 1
    pairs_df = pairs_df.groupby([0, 1]).sum()  # Group identical combinations and count occurences.
    result_df = pairs_df.reset_index(level=1).pivot(columns=1)  # Pivot to create the requested shape.
    

    【讨论】:

      猜你喜欢
      • 2016-03-28
      • 1970-01-01
      • 2014-02-26
      • 2021-04-30
      • 1970-01-01
      • 2011-09-24
      • 1970-01-01
      • 2018-01-20
      • 1970-01-01
      相关资源
      最近更新 更多