Python - Pandas 数据帧串联内存中的气球

问题描述 投票:0回答:2

我的原始数据集是一个关于药物不良反应的 JSON 对象的大型列表。在每个 JSON 对象中,我们可以有几种以 rxcui ids 形式给出不良反应的药物。

我已经获取了 JSON 对象列表并提取了我们需要的重要数据,例如该人是否死亡,以及 rxcui 并将它们压平为最多 2 层深度的 JSON 对象。我们会有这样的东西:

{
  "serious": 1,
  "drug": [
    "DrugA",
    "DrugB",
    "DrugC"
  ],
  "rxcui": [
    100,
    200,
    300
  ]
}

尽我们所能,我必须弄清楚如何将其放入一个数组中,以便将其提供给机器学习算法。所以我的想法是使用one-hot编码。

这就是我使用 countVectorizer 的原因,这样我就可以对所有这些子列表进行矢量化

我正在尝试连接几个 pandas 数据帧(有些是稀疏数据帧,有些是常规数据帧),它们是某些数据的单热编码。我检查了所有文件(我还将它们腌制到硬盘上),没有一个文件大于 81MB。但一旦我开始将它们连接起来,它们就会膨胀到超过 29 GB。这怎么可能?

我所有的 df 看起来都是这样的:

Label0  Label1  Label2  Label3...  Label999
1       1       0       0     ...  0
1       1       0       1     ...  1
.
.
.

我像这样运行 concat:

x = pandas.concat([x, drugcharacterization, occurcountry, reactionmeddrapt, reactionmeddraversionpt, reactionoutcome, rxcui],axis=1, copy=False)

我还可以将我尝试在内存中轻松连接的所有子数据帧放入其中。一旦我这样做,它会爆炸吗?

编辑: 这是我获取数据框的方式。正如我们所看到的,我无法创建其中之一的稀疏矩阵,它给了我一个错误:

raise ValueError("empty vocabulary; perhaps the documents only contain stop words")
import pandas
from sklearn.feature_extraction.text import CountVectorizer    
rr = pandas.DataFrame()
for col in categorical_labels:
    print col
    try:
        vect = CountVectorizer()
        X = vect.fit_transform(z[col].astype(str).map(lambda x: ' '.join(x) if isinstance(x, list) else x))
        r = pandas.SparseDataFrame(X, columns=vect.get_feature_names(), index=z.index, default_fill_value=0).add_prefix(col + ' = ')
        r.to_pickle(col + '_subarr.pkl')
    except:
        r = z[col].astype(str).str.strip('[]').str.get_dummies(', ').add_prefix(col + ' = ')
        r.to_pickle(col + '_subarr.pkl')

    rr = pandas.concat([rr,r], axis=1)

这是他们的不检点:

drugcharacterization.index
Out[13]: RangeIndex(start=0, stop=234372, step=1)

occurcountry.index
Out[14]: RangeIndex(start=0, stop=234372, step=1)

reactionmeddrapt.index
Out[15]: RangeIndex(start=0, stop=234372, step=1)

reactionmeddraversionpt.index
Out[16]: RangeIndex(start=0, stop=234372, step=1)

reactionoutcome.index
Out[17]: RangeIndex(start=0, stop=234372, step=1)

rxcui.index
Out[18]: RangeIndex(start=0, stop=234372, step=1)
python pandas sparse-matrix
2个回答
5
投票

AFAIK

pd.concat([...])
生成一个新的 regular(未稀疏)DataFrame。

考虑以下示例(我使用 Pandas 0.20.1):

源 DF:

In [118]: df
Out[118]:
                                                text
0  With free-text, each letter is actually an ind...
1                As far as the computer is concerned
2  no individual letter or number has any relatio...

In [119]: another
Out[119]:
    a   b   c
0  10  23  87
1  12  45  32
2  14  76  89

让我们对文本进行一次热编码:

from sklearn.feature_extraction.text import CountVectorizer

vect = CountVectorizer(stop_words='english')

# one-hot-encoded
# for Pandas version < 0.20.1 use: vect.fit_transform(df.text).A
ohe = pd.SparseDataFrame(vect.fit_transform(df.text),
                         columns=vect.get_feature_names(),
                         index=df.index,
                         default_fill_value=0)

结果 - SparseDataFrame(注意内存使用情况):

In [127]: ohe
Out[127]:
   actually  computer  concerned  far  free  independent  individual  letter  number  object  relationship  text
0         1         0          0    0     1            1           0       1       0       1             0     1
1         0         1          1    1     0            0           0       0       0       0             0     0
2         0         0          0    0     0            0           1       2       2       0             1     0

In [128]: ohe.memory_usage()
Out[128]:
Index           80
actually         8
computer         8
concerned        8
far              8
free             8
independent      8
individual       8
letter          16
number           8
object           8
relationship     8
text             8
dtype: int64

让我们将此 SparseDataFrame 与源 DF(常规的)连接起来:

In [129]: r = pd.concat([another, df, ohe], axis=1)

In [130]: r
Out[130]:
    a   b   c                                               text  actually  computer  concerned  far  free  independent  individual  \
0  10  23  87  With free-text, each letter is actually an ind...         1         0          0    0     1            1           0
1  12  45  32                As far as the computer is concerned         0         1          1    1     0            0           0
2  14  76  89  no individual letter or number has any relatio...         0         0          0    0     0            0           1

   letter  number  object  relationship  text
0       1       0       1             0     1
1       0       0       0             0     0
2       2       2       0             1     0

In [131]: r.memory_usage()
Out[131]:
Index           80
a               24
b               24
c               24
text            24
actually        24
computer        24
concerned       24
far             24
free            24
independent     24
individual      24
letter          24
number          24
object          24
relationship    24
text            24
dtype: int64

注意:

pd.concat()
创建了一个新的常规DataFrame,因此所有“稀疏”列都变得密集......

对于纯数字 SparseDataFrames 或 SparseArrays,我们可以使用 scipy.sparse.hstack([...]):

In [149]: from scipy import sparse

In [150]: r = pd.SparseDataFrame(sparse.hstack([ohe, another]), 
                                 columns=ohe.columns.append(another.columns))

In [151]: r.memory_usage()
Out[151]:
Index           80
actually         8
computer         8
concerned        8
far              8
free             8
independent      8
individual       8
letter          16
number           8
object           8
relationship     8
text             8
a               24
b               24
c               24
dtype: int64

2
投票

我怀疑您的数据框不共享索引,因此您正在构建比您预期大得多的数据框。

例如,请考虑以下事项:

df1 = pd.DataFrame({'x': [1, 2, 3]}, index=[0, 1, 2])
df2 = pd.DataFrame({'y': [2, 4, 6]}, index=[3, 4, 5])

print(pd.concat([df1, df2], axis=1))
     x    y
0  1.0  NaN
1  2.0  NaN
2  3.0  NaN
3  NaN  2.0
4  NaN  4.0
5  NaN  6.0

这里我们连接两个数据帧,结果是输入的 4 倍,因为索引不共享。对于 7 个数据帧,如果没有共享任何索引,则可能会得到比输入大小约 50 倍的串联结果。

如果没有更多信息,我无法确定您的情况是否如此,但这就是我要开始调查的地方。

© www.soinside.com 2019 - 2024. All rights reserved.