Pandas DataFrame.merge 内存错误
Pandas DataFrame.merge MemoryError
目标
我的目标是通过它们的公共列(基因名称)合并两个 DataFrame,这样我就可以在每个基因行中获取每个基因得分的乘积。然后我会对患者和细胞执行 groupby
并对每个细胞的所有分数求和。最终的数据框应该是这样的:
patient cell
Pat_1 22RV1 12
DU145 15
LN18 9
Pat_2 22RV1 12
DU145 15
LN18 9
Pat_3 22RV1 12
DU145 15
LN18 9
最后一部分应该可以正常工作,但由于 MemoryError
,我无法对基因名称执行第一次合并。以下是每个 DataFrame 的片段。
数据
cell_s =
Description Name level_2 0
0 LOC100009676 100009676_at LN18_CENTRAL_NERVOUS_SYSTEM 1
1 LOC100009676 100009676_at 22RV1_PROSTATE 2
2 LOC100009676 100009676_at DU145_PROSTATE 3
3 AKT3 10000_at LN18_CENTRAL_NERVOUS_SYSTEM 4
4 AKT3 10000_at 22RV1_PROSTATE 5
5 AKT3 10000_at DU145_PROSTATE 6
6 MED6 10001_at LN18_CENTRAL_NERVOUS_SYSTEM 7
7 MED6 10001_at 22RV1_PROSTATE 8
8 MED6 10001_at DU145_PROSTATE 9
cell_s 大约是 10,000,000 行
patient_s =
id level_1 0
0 MED6 Pat_1 1
1 MED6 Pat_2 1
2 MED6 Pat_3 1
3 LOC100009676 Pat_1 2
4 LOC100009676 Pat_2 2
5 LOC100009676 Pat_3 2
6 ABCD Pat_1 3
7 ABCD Pat_2 3
8 ABCD Pat_3 3
....
patient_s 大约是 1,200,000 行
代码
def get_score(cell, patient):
cell_s = cell.set_index(['Description', 'Name']).stack().reset_index()
cell_s.columns = ['Description', 'Name', 'cell', 's1']
patient_s = patient.set_index('id').stack().reset_index()
patient_s.columns = ['id', 'patient', 's2']
# fails here:
merged = cell_s.merge(patient_s, left_on='Description', right_on='id')
merged['score'] = merged.s1 * merged.s2
scores = merged.groupby(['patient','cell'])['score'].sum()
return scores
最初 read_csv
处理这些文件时,我遇到了内存错误,但随后指定数据类型解决了该问题。确认我的 python is 64 bit 也没有解决我的问题。我还没有达到 pandas 的限制,是吗?
Python 3.4.3 |蟒蛇 2.3.0(64 位)| Pandas 0.16.2
你可能需要分块做,或者研究 blaze。 http://blaze.pydata.org
考虑两种解决方法:
CSV 按块
显然,read_csv 可能会遇到性能问题,因此大文件必须以迭代块的形式加载。
cellsfilepath = 'C:\Path\To\Cells\CSVFile.csv'
tp = pd.io.parsers.read_csv(cellsfilepath, sep=',', iterator=True, chunksize=1000)
cell_s = pd.concat(tp, ignore_index=True)
patientsfilepath = 'C:\Path\To\Patients\CSVFile.csv'
tp = pd.io.parsers.read_csv(patientsfilepath, sep=',', iterator=True, chunksize=1000)
patient_s = pd.concat(tp, ignore_index=True)
CSV 威盛 SQL
作为一名数据库专家,我总是建议处理大型数据负载并 merging/joining 使用 SQL 关系引擎,该引擎可以很好地适应此类流程。为此,我写了很多关于数据帧合并 Q/As 的评论 - 即使在 R 中也是如此。您可以使用任何 SQL 数据库,包括文件服务器数据库(Access,SQLite)或客户端服务器数据库(MySQL、MSSQL 或其他),即使在您的 dfs 派生的地方。 Python 为 SQLite 维护一个内置库(否则你使用 ODBC);并且可以使用 pandas to_sql:
将数据帧作为表推送到数据库中
import sqlite3
dbfile = 'C:\Path\To\SQlitedb.sqlite'
cxn = sqlite3.connect(dbfile)
c = cxn.cursor()
cells_s.to_sql(name='cell_s', con = cxn, if_exists='replace')
patient_s.to_sql(name='patient_s', con = cxn, if_exists='replace')
strSQL = 'SELECT * FROM cell_s c INNER JOIN patient_s p ON c.Description = p.id;'
# MIGHT HAVE TO ADJUST ABOVE FOR CELL AND PATIENT PARAMS IN DEFINED FUNCTION
merged = pd.read_sql(strSQL, cxn)
目标
我的目标是通过它们的公共列(基因名称)合并两个 DataFrame,这样我就可以在每个基因行中获取每个基因得分的乘积。然后我会对患者和细胞执行 groupby
并对每个细胞的所有分数求和。最终的数据框应该是这样的:
patient cell
Pat_1 22RV1 12
DU145 15
LN18 9
Pat_2 22RV1 12
DU145 15
LN18 9
Pat_3 22RV1 12
DU145 15
LN18 9
最后一部分应该可以正常工作,但由于 MemoryError
,我无法对基因名称执行第一次合并。以下是每个 DataFrame 的片段。
数据
cell_s =
Description Name level_2 0
0 LOC100009676 100009676_at LN18_CENTRAL_NERVOUS_SYSTEM 1
1 LOC100009676 100009676_at 22RV1_PROSTATE 2
2 LOC100009676 100009676_at DU145_PROSTATE 3
3 AKT3 10000_at LN18_CENTRAL_NERVOUS_SYSTEM 4
4 AKT3 10000_at 22RV1_PROSTATE 5
5 AKT3 10000_at DU145_PROSTATE 6
6 MED6 10001_at LN18_CENTRAL_NERVOUS_SYSTEM 7
7 MED6 10001_at 22RV1_PROSTATE 8
8 MED6 10001_at DU145_PROSTATE 9
cell_s 大约是 10,000,000 行
patient_s =
id level_1 0
0 MED6 Pat_1 1
1 MED6 Pat_2 1
2 MED6 Pat_3 1
3 LOC100009676 Pat_1 2
4 LOC100009676 Pat_2 2
5 LOC100009676 Pat_3 2
6 ABCD Pat_1 3
7 ABCD Pat_2 3
8 ABCD Pat_3 3
....
patient_s 大约是 1,200,000 行
代码
def get_score(cell, patient):
cell_s = cell.set_index(['Description', 'Name']).stack().reset_index()
cell_s.columns = ['Description', 'Name', 'cell', 's1']
patient_s = patient.set_index('id').stack().reset_index()
patient_s.columns = ['id', 'patient', 's2']
# fails here:
merged = cell_s.merge(patient_s, left_on='Description', right_on='id')
merged['score'] = merged.s1 * merged.s2
scores = merged.groupby(['patient','cell'])['score'].sum()
return scores
最初 read_csv
处理这些文件时,我遇到了内存错误,但随后指定数据类型解决了该问题。确认我的 python is 64 bit 也没有解决我的问题。我还没有达到 pandas 的限制,是吗?
Python 3.4.3 |蟒蛇 2.3.0(64 位)| Pandas 0.16.2
你可能需要分块做,或者研究 blaze。 http://blaze.pydata.org
考虑两种解决方法:
CSV 按块
显然,read_csv 可能会遇到性能问题,因此大文件必须以迭代块的形式加载。
cellsfilepath = 'C:\Path\To\Cells\CSVFile.csv'
tp = pd.io.parsers.read_csv(cellsfilepath, sep=',', iterator=True, chunksize=1000)
cell_s = pd.concat(tp, ignore_index=True)
patientsfilepath = 'C:\Path\To\Patients\CSVFile.csv'
tp = pd.io.parsers.read_csv(patientsfilepath, sep=',', iterator=True, chunksize=1000)
patient_s = pd.concat(tp, ignore_index=True)
CSV 威盛 SQL
作为一名数据库专家,我总是建议处理大型数据负载并 merging/joining 使用 SQL 关系引擎,该引擎可以很好地适应此类流程。为此,我写了很多关于数据帧合并 Q/As 的评论 - 即使在 R 中也是如此。您可以使用任何 SQL 数据库,包括文件服务器数据库(Access,SQLite)或客户端服务器数据库(MySQL、MSSQL 或其他),即使在您的 dfs 派生的地方。 Python 为 SQLite 维护一个内置库(否则你使用 ODBC);并且可以使用 pandas to_sql:
将数据帧作为表推送到数据库中import sqlite3
dbfile = 'C:\Path\To\SQlitedb.sqlite'
cxn = sqlite3.connect(dbfile)
c = cxn.cursor()
cells_s.to_sql(name='cell_s', con = cxn, if_exists='replace')
patient_s.to_sql(name='patient_s', con = cxn, if_exists='replace')
strSQL = 'SELECT * FROM cell_s c INNER JOIN patient_s p ON c.Description = p.id;'
# MIGHT HAVE TO ADJUST ABOVE FOR CELL AND PATIENT PARAMS IN DEFINED FUNCTION
merged = pd.read_sql(strSQL, cxn)