【问题标题】:Inserting non duplicate rows in a table without dropping the table在表中插入不重复的行而不删除表
【发布时间】:2022-01-17 14:23:53
【问题描述】:

我想向我的数据库添加一个包含一些重复行的数据框,但由于我的真实数据库非常大,我不想删除现有表并使用更新的行再次添加它,因为它需要我从 API 中再次提取它

我认为正确的方法可能是 df.read_sql() 然后将结果与 df​​2 进行比较,然后只插入尚未存在的行

import sqlalchemy as db
import pandas as pd

engine = db.create_engine('sqlite:///test.db', echo = True)

data1 = {'Month':['June', 'July', 'August'],
        'Number':[20, 21, 19]}
df = pd.DataFrame(data1)
df.to_sql("ExampleTable", engine,if_exists="append", index=False)

data2 = {'Month':['May','June', 'July', 'August', 'Septemper'],
        'Number':[11, 20, 21, 19, 14, 15]}
df2 = pd.DataFrame(data2)
df2.to_sql("ExampleTable", engine,if_exists="append", index=False)

【问题讨论】:

  • “我想从 data2 中追加 data1 中不存在的月份,但按照日历的正确顺序。” 您不应该依赖存储顺序,但考虑数据库表无序集。如需订购,查询时应指定ORDER BY子句。
  • 他们不是。这是事实。获取查询时必须使用ORDER BY 子句。没有其他选择。
  • 是否可以假设您要附加数据的原始表已经作为数据框存储在df1中?似乎您想在数据库中执行此操作,而不是将所有“非常大”的数据拉入数据框中。如果有两个 dfs,一个包含现有数据,一个包含现有+新数据,那么您只需获取 df2 中不存在于 df1 中的行,并将 df2 中的唯一行附加到表中。正如其他作者所说,顺序在写入时并不重要,只在读取时。请澄清以帮助确定解决方案
  • @frederick-douglas-pearce 是的,可以假设原始表已存储为数据帧,所以实际上我想要做的是将数据库作为数据帧读取,然后将其与新的数据框,然后插入不存在的内容

标签: python pandas sqlalchemy


【解决方案1】:

听起来这个问题归结为在新数据帧df2 中查找不在原始数据帧df 中的行,以便df2 唯一的行可以附加到现有的 sql 表。 Stack Overflow 帖子 herehere 中讨论了类似的数据框比较场景。如果您只需要比较“月份”列,那么这应该可以:

df2_month_not_in_df = df2[~df2['Month'].isin(df['Month'])]

但这假设没有空的“月份”值需要担心,不需要包括其他列,如年份等。可以在答案之后实施一种更严格的方法,比较多列中的数据帧行,可能具有空值@toecsnar42 和上面 SO 链接中的其他人:

df_str_tuples = df.astype(str).apply(tuple, 1)
df2_str_tuples = df2.astype(str).apply(tuple, 1)
df2_rows_in_df_filter = df2_str_tuples.isin(df_str_tuples)
df2_rows_not_in_df = df2[~df2_rows_in_df_filter]

对于每个数据框,将所有值转换为字符串类型,这会将缺失值更改为“nan”,然后通过将每列中的值组合成每行的单个元组来创建一个系列。接下来,创建一个掩码,只要df2 的行与df 中的行匹配,该掩码就为真。最后,将df2 数据框过滤到掩码为假的行(即不在df 中),这将构建数据框df2_rows_not_in_df,可以使用to_sql 和@ 将其附加到现有的sql 表中987654334@。 过去帖子中的其他实现方法使用 pd.mergepd.concat 方法,因此根据您的用例考虑不同的选项。

【讨论】:

    【解决方案2】:

    所以只是为了澄清一些事情。

    1. SQLite 不会根据数据按顺序存储事物。它根据 ROW ID 存储它。但是,您可以检索数据,然后让 sqlite 根据 sql 查询中的列对返回的数据进行排序。

    2. 您要求插入数据,然后在第二个请求中修改或更新该数据。 Dataframes 并没有真正提供这种类型的功能。据我了解,熊猫可以插入到已经存在的表中或删除表并插入新数据。所以这是你很可能必须运行原始 sql 查询才能实现的。这篇文章展示了有人在 sql 中为 pandas 执行所谓的“upsert”,但要求他们创建一个临时表并使用该表来修改原始表中的数据。 How do I perform an UPDATE of existing rows of a db table using a Pandas DataFrame?

    【讨论】:

      猜你喜欢
      • 2021-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多