Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在使用Pandas或普通SQL插入SQLite数据库之前,规范化CSV数据_Python_Postgresql_Sqlite_Pandas_Csv - Fatal编程技术网

Python 在使用Pandas或普通SQL插入SQLite数据库之前,规范化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慢 在插入数据库之前,如何将这些数据

以下是我想要完成的任务的示意图:

实际的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()
导入全局
作为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(新参数)