Python 在使用Pandas或普通SQL插入SQLite数据库之前,规范化CSV数据
以下是我想要完成的任务的示意图: 实际的CSV文件在相当于Python 在使用Pandas或普通SQL插入SQLite数据库之前,规范化CSV数据,python,postgresql,sqlite,pandas,csv,Python,Postgresql,Sqlite,Pandas,Csv,以下是我想要完成的任务的示意图: 实际的CSV文件在相当于Name/Phone组合的每个组合中可能有数万或数十万行,这会浪费大量内存和磁盘空间。我知道如何使用SQL规范化数据库中的数据,但我希望首先避免复制所有重复的数据,而是插入外键关系。这些列中重复的值所消耗的磁盘空间相当大 目前,我正在使用Python和Pandas自动化创建SQLite数据库并将数据插入其中的过程。我也为此尝试了PostgreSQL,但由于某些原因,我发现它比pandas+sqlite慢 在插入数据库之前,如何将这些数据
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()
导入全局
作为pd进口熊猫
导入sqlite3
def read_nlines(文件:str,n:int=10)->pd.DataFrame:
返回pd.read_csv(文件,nrows=n,comment='#',skip_blank_lines=True,
sep='\t',encoding='utf-8')
conn=sqlite3.connect(“data.db”)
cur=连接光标()
files=glob.glob(“data/*.txt”)
对于文件中的文件:
数据=读取线(文件)
###--->
###--->在写入sql之前,我想在这里转换数据
data.to_sql('table',con=conn,如果存在='replace')
康涅狄格州关闭
您可以使用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
编辑:
您可以使用
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
编辑:
请随意使用您喜欢的任何数据结构,但这对我来说是有意义的 将csv文件中的每一行加载到包含两个词典的列表中。一个字典用于您的人员相关字段,另一个字典用于其他字段。你可以使用csv库来实现这一点,但我想如果你已经做到了这一点,你已经有了一个实现这一点的过程 然后,创建一个人员词典列表,仅在列表中没有词典时才在中添加词典 然后,您可以在原始列表中循环,并将personKey添加到每个子列表中的第二个字典中。将此列表的键设置为人员词典列表中人员词典的索引
dictList = [
[{'Name': 'Bob', 'Phone': '098-765-4321'}, {'S1': 0.36, 'S2': 0.91, 'S3': 0.24}],
[{'Name': 'Bob', 'Phone': '098-765-4321'}, {'S1': 0.44, 'S2': 0.36, 'S3': 0.78}],
[{'Name': 'Steve', 'Phone': '768-098-1234'}, {'S1': 0.55, 'S2': 0.15, 'S3': 0.74}]
]
personRecords = []
numberRecords = []
for item in dictList:
numberRecord = item[1]
if item[0] not in personRecords:
personRecords.append(item[0])
numberRecord['personKey'] = personRecords.index(item[0])
numberRecords.append(numberRecord)
for person in personRecords:
print(person)
for record in numberRecords:
print(record)
然后,您可以获取每个字典列表,将它们解析为数据库库所需的任何数据结构,然后上载。请随意使用您喜欢的任何数据结构,但这对我来说是有意义的 将csv文件中的每一行加载到包含两个词典的列表中。一个字典用于您的人员相关字段,另一个字典用于其他字段。你可以使用csv库来实现这一点,但我想如果你已经做到了这一点,你已经有了一个实现这一点的过程 然后,创建一个人员词典列表,仅在列表中没有词典时才在中添加词典 然后,您可以在原始列表中循环,并将personKey添加到每个子列表中的第二个字典中。将此列表的键设置为人员词典列表中人员词典的索引
dictList = [
[{'Name': 'Bob', 'Phone': '098-765-4321'}, {'S1': 0.36, 'S2': 0.91, 'S3': 0.24}],
[{'Name': 'Bob', 'Phone': '098-765-4321'}, {'S1': 0.44, 'S2': 0.36, 'S3': 0.78}],
[{'Name': 'Steve', 'Phone': '768-098-1234'}, {'S1': 0.55, 'S2': 0.15, 'S3': 0.74}]
]
personRecords = []
numberRecords = []
for item in dictList:
numberRecord = item[1]
if item[0] not in personRecords:
personRecords.append(item[0])
numberRecord['personKey'] = personRecords.index(item[0])
numberRecords.append(numberRecord)
for person in personRecords:
print(person)
for record in numberRecords:
print(record)
然后,您可以获取每个字典列表,将它们解析为数据库库所需的任何数据结构,然后上载。那么,实际的问题是什么?实际的问题是什么?有什么方法可以跨调用实现这一点?这些文件需要分块处理,我想知道如何保存
factorize
的结果,以便在不同的数据帧上运行它不会重置factorize
?@mooglinux提供的索引。在这里如何处理块,如果在for循环中,您需要再添加一个参数a参数用于什么?类别?添加到原始问题中。@mooglinux检查更新:-)您将看到ncount(新参数)是否有任何方法可以跨调用执行此操作?这些文件需要分块处理,我想知道如何保存factorize
的结果,以便在不同的数据帧上运行它不会重置factorize
?@mooglinux提供的索引。在这里如何处理块,如果在for循环中,您需要再添加一个参数a参数用于什么?类别?添加到原始问题。@mooglinux检查更新:-)您将看到ncount(新参数)