Pandas DataFrame.fusionner MemoryError

but

mon but est de fusionner deux images de données par leur colonne commune (noms de gènes) afin que je puisse prendre un produit de chaque score de gène à travers chaque rangée de gènes. Je puis à effectuer un groupby sur les patients et les cellules et additionner tous les scores de chacun. L'ultime bloc de données devrait ressembler à ceci:

    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

la dernière partie devrait fonctionner correctement, mais je n'ai pas été en mesure d'effectuer la première fusion sur les noms des gènes en raison d'un MemoryError. Ci-dessous sont extraits de chaque 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 est d'environ 10 000 000 de lignes

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 est d'environ de 1 200 000 lignes

Code

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

j'ai été faire un MemoryError lors du début de l' read_csv ces fichiers, mais en spécifiant les dtypes ont résolu le problème. Confirmant que mon python est de 64 bits n'a pas résolu mon problème. Je n'ai pas atteint le des limites sur les pandas, n'est-ce pas?

Python 3.4.3 / Anaconda 2.3.0 (64-bit) / Pandas 0.16.2

8
demandé sur Community 2015-08-01 21:58:22

2 réponses

Envisager deux solutions:

CSV By CHUNKS

Apparemment, read_csv peut souffrir de problèmes de performance et donc les gros fichiers doivent se charger en morceaux itérés.

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 VIA SQL

en tant que type de base de données, je recommande toujours de traiter de grandes charges de données et de fusionner/joindre avec un moteur relationnel SQL qui se balance bien pour de tels processus. J'ai écrit de nombreux commentaires sur DataFrame fusionner Q / As à cet effet-même en R. Vous pouvez utiliser N'importe quelle base de données SQL y compris DBS de serveur de fichiers (Accès, SQLite) ou DBS de serveur client (MySQL, MSSQL, ou autre), même où votre DFS dérivent. Python maintient une bibliothèque intégrée pour SQLite (sinon vous utilisez ODBC); et les dataframes peuvent être poussés dans les bases de données en tant que tables en utilisant 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)
5
répondu Parfait 2017-05-23 12:26:15

vous pourriez avoir à le faire en morceaux, ou regarder dans le feu. http://blaze.pydata.org

1
répondu Skorpeo 2015-08-01 22:23:09