将sql代码转换为python pandas dataframe操作

时间:2018-06-04 13:29:26

标签: python pandas sqlite

所以我在处理和处理大量数据方面遇到了麻烦 我的表1由2个百万个记录组成,例如:

TABLE1
ID; AGE; SEX;
1; 1; F
2; 1; F
3; 1; M
4; 2; F
4; 2; m

和另一个包含数据的表:

TABLE2
TYPE, SEX, AGE_RANGE
1, F, 1-5
1, F, 6-10
1, F, 11-15
2, F, 1-5
1, M, 1-5
2, M, 1-5

我正在创建一个联接:

SELECT tbl1.id, tbl1.age, tbl2.sex, table2.type
FROM table1 tbl1, table2 tbl2
WHERE 
tbl1.age >= tbl2.min_age AND tbl1.age <= tbl2.max_age AND
tbl1.sex = tbl2.sex

结果是一个非常大的表(SELECT应该返回大约40milions行 然后我使用groupby和filter方法来进一步过滤我的记录。我有一个问题,因为我在运行代码时遇到了MemmoryError。我正在考虑改变csv以更好地容纳pandas数据帧(以避免使用sql) 我的代码示例如下:

df_table1 = pd.read_csv(table1)
df_table2 = pd.read_csv(table2)
conn = sqlite3.connect(':memory:')

df_table1.to_sql('table1', conn, index=False)
df_table2.to_sql('table2', conn, index=False)

sql = '''SELECT tbl1.id, tbl1.age, tbl2.sex, table2.type
FROM table1 tbl1, table2 tbl2
WHERE 
tbl1.age >= tbl2.min_age AND tbl1.age <= tbl2.max_age AND
tbl1.sex = tbl2.sex'''

df_filtered = pd.read_sql_query(sql, conn)

filter = ['sex', 'age_range', 'type']
grouped_data = df_filtered.groupby(iskanje).apply(select_random_row)
#select_random_row is my custom_made function which returns just select few rows that groupby returns
grouped_data .to_csv("result.csv", sep=';', encoding='utf-8') 

最大的问题是我的sql,因为我没有记忆错误,但即使没有错误,它只需要很长时间来加载它。我正在考虑更改我的csv并使用精确的AGE而不是AGE_RANGE ....这将允许我使用pandas查询而不是sql

2 个答案:

答案 0 :(得分:0)

我认为你可以这样做:

void

这里我在两个表中创建一个新的table1['AGE_RANGE'] = pd.cut(table1['AGE'], np.linspace(0, 80, 17)) table2['AGE_RANGE_fmt'] = pd.cut(table2['AGE_RANGE'].str.split('-').str[0].astype('int'), np.linspace(0, 80, 17)) df_filtered = table1.merge(table2, how='left', left_on=['SEX', 'AGE_RANGE'], right_on=['SEX', 'AGE_RANGE_fmt']) 列,并将其用作合并的键。

答案 1 :(得分:0)

我设法以相当不错的性能完成了我的问题。

我用循环来循环到df2中的每个不同的TYPE(它是固定大小,有20种不同的类型)。 每次迭代我使用df.merge来合并AGE_GROUP和SEX上的两个表(我将列AGE_GROUP添加到table1。 然后我在SEX和AGE_GROUP上使用groupby,并在这些组上使用自定义过滤器。 整个过程大约需要15分钟才能完成,但至少我没有用完公羊。