在使用Pandas或纯SQL插入SQLite数据库之前规范化CSV数据

时间:2017-12-08 23:01:06

标签: python postgresql sqlite pandas csv

这是我想要完成的图表: Desired data transformation

实际的CSV文件每个等效的Name/Phone组合可能有数万或数十万行,这会浪费大量的内存和磁盘空间。我知道如何使用SQL实际在数据库中规范化这些数据,但我希望避免首先复制所有这些重复数据,而是插入外键关系。这些列中重复值占用的磁盘空间相当大。

目前我正在使用Python和Pandas来自动创建SQLite数据库并将数据插入其中。我也尝试过PostgreSQL,但由于某种原因发现它比pandas + sqlite慢。

如何在插入数据库之前将此数据拆分为多个表?

编辑由于文件的大小,我正在处理它们,如下所示:

import glob
import pandas as pd
import sqlite3


def read_nlines(file: str, n: int = 10) -> pd.DataFrame:
    return pd.read_csv(file, nrows=n, comment='#', skip_blank_lines=True,
                       sep='\t', encoding='utf-8')


conn = sqlite3.connect("data.db")
cur = conn.cursor()

files = glob.glob("data/*.txt")

for file in files:
    data = read_nlines(file)
###--->
###---> This is where I want to transform the data, before writing to sql <---###
###--->
    data.to_sql('table',con=conn,if_exists='replace')

conn.close()

2 个答案:

答案 0 :(得分:1)

您可以使用pandas

df=pd.DataFrame({'Name':['Joe','Bob','Bob','Bob','Steve','Steve','Steve'],'Phone':['111','222','222','222','333','333','333'],'S1':[1,2,3,4,5,6,7],'S2':[1,2,3,4,5,6,7],'S3':[1,2,3,4,5,6,7]})
df['ID']=pd.factorize(df['Name'])[0]+1
sql1=df[['ID','S1','S2','S3']]
sql2=df[['ID','Name','Phone']].drop_duplicates()
sql1
Out[729]: 
   ID  S1  S2  S3
0   1   1   1   1
1   2   2   2   2
2   2   3   3   3
3   2   4   4   4
4   3   5   5   5
5   3   6   6   6
6   3   7   7   7
sql2
Out[730]: 
   ID   Name Phone
0   1    Joe   111
1   2    Bob   222
4   3  Steve   333

编辑:

ncount=1
for file in files:
    data = read_nlines(file)


    data['ID'] = pd.factorize(data['Name'])[0] + ncount
    ncount+=data['Name'].nunique()
    sql1 = df[['ID', 'S1', 'S2', 'S3']]
    sql2 = df[['ID', 'Name', 'Phone']].drop_duplicates()

答案 1 :(得分:0)

随意使用您喜欢的任何数据结构,但这对我来说是有意义的。

将csv文件中的每一行加载到两个词典的列表中。一个字典用于与人相关的字段,一个用于其他字段。你可以使用csv库 - 但是我想如果你已经到了这个目的,你已经有了一个适当的流程。

然后,创建一个人物词典列表,只有在词典不在列表中时才添加词典。

然后,您可以遍历原始列表列表,并将personKey键添加到每个子列表中的第二个字典中。将此列表的键设置为等于人物词典列表中人物词典的索引。

ab = function(m, s, lo = -Inf, hi = Inf){

loop = if(length(m) > 1) length(m) else length(s)

for(i in 1:loop){

p = function(x) dnorm(x, m[i], s[i])  # [i] should be either for `m` or `s` but what can I do here to have [i] be selectively chosen?
f = function(x) p(x)/integrate(p, lo, hi)[[1]]
curve(f, -3, 3, add = i!= 1, col = i)
    }
}
# Example of use:
ab(m = c(0, .5), s = 1) # Error in integrate(p, lo, hi) : non-finite function value

然后,您可以获取每个字典列表,将它们解析为数据库库所需的任何数据结构,然后上载。

相关问题