【问题标题】:Pandas Import not Inserting All Rows熊猫导入未插入所有行
【发布时间】:2019-03-13 12:22:31
【问题描述】:

我正在通过以下方式导入一个包含 3300 行数据的 .csv 文件:

myCSVfile = pd.read_csv(csv_file)
myCSVfile.to_sql(con=engine, name='foo', if_exists='replace')

成功导入后,我对表执行“select * from ...”查询,返回 3100 行,那么缺少的 200 行在哪里?

我假设存在无法读取的损坏数据,我进一步假设它会被 pandas 跳过。但是,没有任何警告、日志或消息可以明确说明。脚本正常执行。

有没有人遇到过类似的问题,还是我遗漏了一些非常明显的问题?

【问题讨论】:

  • 有点不清楚你认为它失败的地方。您是否检查过从文件中读取了多少行?例如myCSVfile.shape
  • 会不会是 csv 文件包含重复键?你确实使用了 if_exists='replace'。
  • 如果描述含糊不清,我们深表歉意。简而言之,是的,我在流程的每个阶段都运行了多次打印以跟踪所有内容,并且数字仅在导入后有所不同,这就是为什么我认为问题出在 .to_sql 函数中。 @JohnSloper
  • @Spinor8 我也检查了重复项,是的,我发现了
  • if_exists 适用于数据库实体以及如何处理它。它可以“附加”到其他行为中。但不应为丢失行负责。

标签: mysql python-3.x pandas csv


【解决方案1】:

虽然问题没有指定engine,但我们假设它是sqlite3

以下可重新运行的代码显示 DataFrame.to_sql() 创建了一个 sqlite3 表,并在其上放置了一个索引。哪个是数据框索引中的数据。

从字面上看问题代码,csv 应该使用 RangeIndex 导入 DataFrame,这将是唯一的序数。因此,如果 csv 中的行数与加载到 sqlite3 表中的行数不匹配,应该会感到惊讶。

所以有两件事要做:验证 csv 是否被正确导入。这可能是问题所在,因为源自人工操作的电子表格的格式不正确的 csv 文件在被代码操作时由于各种原因经常失败。但这不可能在这里回答,因为我们不知道输入数据。

但是,DataFrame.to_sql() 所做的应该被排除在外。为此,可以传入method。它可以用来查看DataFrame.to_sql() 在将DataFrame 数据交给SQL engine 之前做了什么。

import csv
import pandas as pd
import sqlite3

def dump_foo(conn):
    cur = conn.cursor()
    cur.execute("SELECT * FROM foo")
    rows = cur.fetchall()
    for row in rows:
        print(row)

conn = sqlite3.connect('example145.db')

csv_data = """1,01-01-2019,724
2,01-01-2019,233,436
3,01-01-2019,345
4,01-01-2019,803,933,943,923,954
4,01-01-2019,803,933,943,923,954
4,01-01-2019,803,933,943,923,954
4,01-01-2019,803,933,943,923,954
4,01-01-2019,803,933,943,923,954
5,01-01-2019,454
5,01-01-2019,454
5,01-01-2019,454
5,01-01-2019,454
5,01-01-2019,454"""

with open('test145.csv', 'w') as f:
    f.write(csv_data)

with open('test145.csv') as csvfile:
    data = [row for row in csv.reader(csvfile)]
df = pd.DataFrame(data = data)

def checkit(table, conn, keys, data_iter):
    print "What pandas wants to put into sqlite3"
    for row in data_iter:
        print(row)

# note, if_exists replaces the table and does not affect the data
df.to_sql('foo', conn, if_exists="replace", method=checkit)
df.to_sql('foo', conn, if_exists="replace")
print "*** What went into sqlite3"
dump_foo(conn)

【讨论】:

    猜你喜欢
    • 2016-01-14
    • 2020-09-25
    • 2023-03-13
    • 2016-12-31
    • 2023-04-01
    • 2018-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多