【问题标题】:Python - Search multiple columns for string to set categorical variable valuePython - 在多个列中搜索字符串以设置分类变量值
【发布时间】:2017-11-15 13:14:35
【问题描述】:

我对 Python 和 Pandas 非常陌生,我正在尝试使用它来对一个非常大的数据集(1000 万个案例)进行统计分析,因为其他选项(SPSS 和 R)无法处理授权的数据集硬件。

在此分析中,我需要逐行搜索一系列列(准确地说是 30 个)以提取单个字符串(可能有大约 200 个,不确定数据集中实际存在多少),然后创建一个每个字符串的分类变量。

数据是这样的

  Dx1     Dx2     Dx3   etc... 
  001     234     456 
  231     001     444
  245     777     001

需要的是

Dx1     Dx2     Dx3  Var001   Var234  Var456  Var231   etc..   
001     234     456  True     True    True    False
231     001     444  True     False   False   True
245     777     001  True     False   False   False

关于如何做到这一点的任何想法?


df.dtypes 展示

AGE                      int64
DISPUNIFORM              int64
DRG                      int64
DRGVER                   int64
Readmit_30D              int64
DXCCS1                   int64
DXCCS2                   int64
DXCCS3                   int64
DXCCS4                   int64
...on to DXCCS30

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    我认为您希望将“一个热编码”数据集保留为 sparse 矩阵。

    所以尝试以下节省内存的方法:

    from sklearn.feature_extraction.text import CountVectorizer
    
    cv = CountVectorizer()
    
    r = pd.SparseDataFrame(cv.fit_transform(df.astype(str).add(' ').sum(axis=1)),
                           columns=cv.get_feature_names(),
                           index=df.index,
                           default_fill_value=0).add_prefix('Var')
    

    结果:

    In [85]: r
    Out[85]:
       Var001  Var231  Var234  Var245  Var444  Var456  Var777
    0       1       0       1       0       0       1       0
    1       1       1       0       0       1       0       0
    2       1       0       0       1       0       0       1
    
    In [86]: r.memory_usage()
    Out[86]:
    Index     80
    Var001    24
    Var231     8
    Var234     8
    Var245     8
    Var444     8
    Var456     8
    Var777     8
    dtype: int64
    

    解释:

    为了将所有数据收集到一列中,我使用了以下技巧:

    In [89]: df.astype(str).add(' ').sum(axis=1)
    Out[89]:
    0    001 234 456
    1    231 001 444
    2    245 777 001
    dtype: object
    

    PS 不要将生成的稀疏 DF 与源 DF 连接,因为它可能会导致它“爆炸”回正常(非稀疏)DF:

    In [87]: df.join(r)
    Out[87]:
       Dx1  Dx2  Dx3  Var001  Var231  Var234  Var245  Var444  Var456  Var777
    0  001  234  456       1       0       1       0       0       1       0
    1  231  001  444       1       1       0       0       1       0       0
    2  245  777  001       1       0       0       1       0       0       1
    
    In [88]: df.join(r).memory_usage()
    Out[88]:
    Index     80
    Dx1       24
    Dx2       24
    Dx3       24
    Var001    24
    Var231    24
    Var234    24
    Var245    24
    Var444    24
    Var456    24
    Var777    24
    dtype: int64
    

    【讨论】:

    • 运行 SparseDataFrame 的代码时,返回“TypeError: Could not compare [' '] with block values”。
    • @RROBINSON,你能发布df.dtypes的输出吗?
    • 添加到问题正文的 dtypes。它们大多是 int64。
    • @RROBINSON,您可能想先将它们转换为字符串 - 我已经相应地更新了我的答案...
    • 效果很好。谢谢。
    【解决方案2】:

    get_dummiesmax 一起使用,转换为bool,最后将join 转换为原始:

    df = (df.join(pd.get_dummies(df, prefix_sep='', prefix='')
                    .max(level=0, axis=1)
                    .astype(bool)
                    .add_prefix('Var')))
    print (df)
    
       Dx1  Dx2  Dx3  Var001  Var231  Var245  Var234  Var777  Var444  Var456
    0  001  234  456    True   False   False    True   False   False    True
    1  231  001  444    True    True   False   False   False    True   False
    2  245  777  001    True   False    True   False    True   False   False
    

    【讨论】:

    • 我认为这不适合 OP 的记忆... :(
    • @jezrael 我无法理解“.max (level = 0, axis = 1)”,为什么添加 level = 0 会合并具有相同列名的列,而不是添加级别= 0 会计算每一行的最大元素而不区分列名吗?另外“pd.get_dummies(df,prefix_sep = '',prefix = '')”获取DataFrame的索引是“RangeIndex(start = 0,stop = 3,step = 1)”类型,是看不到的作为多索引结构?如果方便的话,谢谢您的回答。
    • @AYI - 如果仅使用 pd.get_dummies(df, prefix_sep='', prefix=''),则会创建重复的列名。因此添加了.max (level = 0, axis = 1) 用于按列分组并获得最大值,不使用总和,因为如果相同列中的值1 它返回2,并且指标列应该只包含01。所以如果 double 1 它返回最大值是 1
    • @AyiF - df = df.groupby(level=0, axis=1).max() 的快捷方式与 df = df.max (level = 0, axis = 1) 相同
    • @jezrael 这是我第一次接触到 groupby 同时使用关键字参数“级别和轴”。我已经输入了代码以进行初步了解。谢谢您的回答。值得学习。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 2016-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多