W symulacji Monte-Carlo przechowuję podsumowanie każdego uruchomienia w pliku danych, w którym każda kolumna zawiera parametr lub jeden z wartości wynikowych. Skończę więc z dużym plikiem danych, w którym przechowywane jest do 40 kolumn danych, w których wiele rzędów nie ma nic wspólnego z innymi.

Powiedz na przykład ten plik wygląda tak:

#param1    param2    result1    result2
1.0        1.0       3.14       6.28
1.0        2.0       6.28       12.56
...
2.0        1.0       1.14       2.28
2.0        2.0       2.28       4.56

Ponieważ często chcę studiować zależność jednego z wyników na jednym z parametrów, obaj potrzebuję do grupy przez drugi parametr i sortuj według pierwszej. Również mogę również filtrować wiersze w zależności od dowolnych parametrów.

Zacząłem pisać na ten temat na to, ale wydaje się trudniejsze niż można się domyślić. Teraz moje pytanie: Czy jest jakaś biblioteka, która już to robi? Albo, ponieważ znam SQL, czy trudno byłoby napisać backend SQL, powiedzmy, Sqlalchemy, który pozwala mi robić proste zapytania SQL na moich danych? O ile wiem, zapewniłoby to wszystko, czego potrzebuję.


W oparciu o odpowiedź Cravoori (lub przynajmniej jeden na link, który opublikował), oto ładne i krótkie rozwiązanie mojego problemu:

#!/usr/bin/python2

import numpy as np
import sqlite3 as sql

# number of columns to read in
COLUMNS = 31

# read the file. My columns are always 18chars long. the first line are the names
data = np.genfromtxt('compare.dat',dtype=None,delimiter=18, autostrip=True,
                     names=True, usecols=range(COLUMNS), comments=None)

# connect to the database in memory
con = sql.connect(":memory:")

# create the table 'data' according to the column names
con.execute("create table data({0})".format(",".join(data.dtype.names)))

# insert the data into the table
con.executemany("insert into data values (%s)" % ",".join(['?']*COLUMNS),
                data.tolist())

# make some query and create a numpy array from the result
res = np.array(con.execute("select DOS_Exponent,Temperature,Mobility from data ORDER \
    BY DOS_Exponent,Temperature ASC").fetchall())

print res
1
janoliver 30 lipiec 2012, 20:26

3 odpowiedzi

Najlepsza odpowiedź

Widząc, że dane są rozdzielone, jedna opcja jest importowanie pliku do bazy danych SQLite w pamięci przez moduł CSV, przykład połączony poniżej. Sqlite obsługuje większość klauzul SQL

Importuj dane do SQLite DB

2
Community 23 maj 2017, 11:44

Zakładając, że wymagane są tylko proste obliczenia, podejście w kodeksie może być czymś wzdłuż następujących linii:

file = open('list_filter_data.txt', mode='r')
lines = file.read().splitlines()
row_sets = [[float(c) for c in line.split()] for line in lines[1:]] # read and split the lines in the columns

# get only rows whose param1 = 1.0
subset = [row for row in row_sets if row[0] == 1.0]
print subset
# get only rows whose param1 = 2.0
subset = [row for row in row_sets if row[0] == 2.0]
print subset
# average result1 where param2 = 2.0
avg = sum([row[2] for row in row_sets if row[1] == 2.0]) / len([row[2] for row in row_sets if row[1] == 2.0])
print avg
0
Nisan.H 30 lipiec 2012, 17:02

Jeśli rozmiar pliku jest kolejnością kilku MBS, możesz łatwo przeczytać tę pamięć i rozwiązać za pomocą innych odpowiedzi.

Jeśli rozmiar pliku jest kilkaset MBS lub kilku GBS, lepiej byłoby korzystać z leniwej metody ładowania, takiego jak opisany tutaj - Leniwy metodę czytania Big Plik w Pythonie?

Jeśli obliczenie, które zamierzasz zrobić, można zrobić wiersz, to te małe kawałki powinny być odpowiednie dla Ciebie, aby zrobić wszystko, czego potrzebujesz.

W przeciwnym razie utwórz tabelę SQL z kolumnami C1, C2, Po prostu użyj API dostępu do bazy API bazy danych Pythona, aby napisać instrukcje SQL i analizować wszystko, czego potrzebujesz.

Z drugiej strony, arkusze kalkulacyjne Excel mogą również rozwiązać swój problem

0
Community 23 maj 2017, 12:30