python - 使用 python 更新/更新数据表
问题描述
我想要一些关于如何使用 Python/Databricks 将新数据更新/插入到现有数据表中的建议:
# Inserting and updating already existing data
# Original data
import pandas as pd
source_data = {'Customer Number': ['1', '2', '3'],
'Colour': ['Red', 'Blue', 'Green'],
'Flow': ['Good', 'Bad', "Good"]
}
df1 = pd.DataFrame (source_data, columns = ['Customer Number','Colour', 'Flow'])
print(df1)
# New data
new_data = {'Customer Number': ['1', '4',],
'Colour': ['Blue', 'Blue'],
'Flow': ['Bad', 'Bad']
}
df2 = pd.DataFrame (new_data, columns = ['Customer Number','Colour', 'Flow'])
print(df2)
# What the updated table will look like
updated_data = {'Customer Number': ['1', '2', '3', '4',],
'Colour': ['Blue', 'Blue', 'Green', 'Blue',],
'Flow': ['Bad', 'Bad', "Good", 'Bad']
}
df3 = pd.DataFrame (updated_data, columns = ['Customer Number','Colour', 'Flow'])
print(df3)
在这里你可以看到原始数据有三个客户。然后我得到“new_data”,其中包含客户 1 数据的更新和“客户 4”的新数据,他们不在原始数据中。然后,如果您查看“updated_data”,您可以看到最终数据应该是什么样子。此处“客户 1”的数据已更新,客户 4 的数据已插入。
有谁知道我应该从哪里开始?我可以使用哪个模块?
我不指望有人在发展方面解决这个问题,只需要朝着正确的方向轻推。
编辑:数据源是 .txt 或 CSV,输出是 JSON,但是当我将数据加载到 Cosmos DB 时,它会自动转换,所以不要太担心。
谢谢
解决方案
当前数据帧结构和“pd.update”
通过一些准备,您可以使用 pandas 的“更新”功能。首先,必须对数据帧进行索引(这通常很有用)。其次,源数据帧必须由具有虚拟/NaN 数据的新索引扩展,以便可以更新。
# set indices of original data frames
col = 'Customer Number'
df1.set_index(col, inplace=True)
df2.set_index(col, inplace=True)
df3.set_index(col, inplace=True)
# extend source data frame by new customer indices
df4 = df1.copy().reindex(index=df1.index.union(df2.index))
# update data
df4.update(df2)
# verify that new approach yields correct results
assert all(df3 == df4)
当前数据帧结构和'pd.concat'
一种稍微简单的方法连接数据框并删除重复的行(如果需要,还可以按索引排序)。但是,临时级联需要更多内存,这可能会限制数据帧的大小。
df5 = pd.concat([df1, df2])
df5 = df5.loc[~df5.index.duplicated(keep='last')].sort_index()
assert all(df3 == df5)
替代数据结构
鉴于“客户编号”是您数据的关键属性,您还可以考虑像这样重组您的原始字典:
{'1': ['Red', 'Good'], '2': ['Blue', 'Bad'], '3': ['Green', 'Good']}
然后更新您的数据只是对应于(重新)使用新数据设置源数据的键。通常,直接处理字典比使用数据帧要快。
# define function to restructure data, for demonstration purposes only
def restructure(data):
# transpose original data
# https://stackoverflow.com/a/6473724/5350621
vals = data.values()
rows = list(map(list, zip(*vals)))
# create new restructured dictionary with customers as keys
restructured = dict()
for row in rows:
restructured[row[0]] = row[1:]
return restructured
# restructure data
source_restructured = restructure(source_data)
new_restructured = restructure(new_data)
# simply (re)set new keys
final_restructured = source_restructured.copy()
for key, val in new_restructured.items():
final_restructured[key] = val
# convert to data frame and check results
df6 = pd.DataFrame(final_restructured, index=['Colour', 'Flow']).T
assert all(df3 == df6)
PS:设置 'df1 = pd.DataFrame(source_data, columns=[...])' 时,您不需要 'columns' 参数,因为您的字典名称很好,并且键会自动作为列名。
推荐阅读
- c++ - 使用 CMake 生成自定义头文件
- asp.net-core - 客户端拨打电话时如何识别用户?
- swift - 溢出运算符的效率是否低于执行不会导致溢出的操作?
- javascript - 如何在 Angular 中动态填充下拉列表(Syncfusion Scheduler)
- typescript - vue composition api“参考或反应”是否在模板上具有深度反应?
- python - 循环遍历 csv 文件中以该列表中的元素开头的列中的关键字列表 - Python
- javascript - 从嵌套数组和嵌套对象数组中过滤对象数组
- c++ - 如何创建可变数量的线程?
- react-native - React Native Error Advice - 开发服务器返回响应错误代码:500
- python - 如何抑制python中的try except block打印出的错误