Python 使用pyarrow编写带有结构的拼花地板文件时出错 问题
我在使用pyarrow为拼花地板编写结构时遇到问题。根据数据集的大小,似乎存在间歇性故障。如果我对数据集进行子采样或超级采样,它有时会编写有效的数据集,有时则不会。我看不出有什么规律 我正在写一个列,带有模式Python 使用pyarrow编写带有结构的拼花地板文件时出错 问题,python,hive,parquet,pyarrow,apache-arrow,Python,Hive,Parquet,Pyarrow,Apache Arrow,我在使用pyarrow为拼花地板编写结构时遇到问题。根据数据集的大小,似乎存在间歇性故障。如果我对数据集进行子采样或超级采样,它有时会编写有效的数据集,有时则不会。我看不出有什么规律 我正在写一个列,带有模式 struct<creation_date: string, expiration_date: string, last_updated: string, name_server: string, registrar: string,
struct<creation_date: string,
expiration_date: string,
last_updated: string,
name_server: string,
registrar: string,
status: string>
奇怪的是,其他数据类型看起来很好——这个特定的结构有点抛出错误。以下是重现问题所需的代码:
将熊猫作为pd导入
将pyarrow作为pa导入
导入pyarrow.parquet作为pq
导入系统
#命令行参数,用于设置数据集中的行数
_,n=sys.argv
n=int(n)
#随机whois数据-应为具有架构的结构
#结构
#没什么特别有趣的
df=pd.DataFrame({'whois':[
{'registrator':'GoDaddy.com,LLC','creation_date':'2020-07-17T16:10:35','expiration_date':'2022-07-17T16:10:35','last_updated':None','name_server':'ns59.domaincontrol.com\r','status':'clientdeleteProbited',
{“注册人”:“香港域名信息管理有限公司”,“创建日期”:“2020-07-17T10:28:36”,“到期日期”:“2021-07-17T10:28:36”,“上次更新”:无,“名称服务器”:“ns2.alidns.com\r”,“状态”:“ok”},
{'registrator':'GoDaddy.com,LLC','creation_date':'2020-07-17T04:04:06','expiration_date':'2021-07-17T04:04:06','last_updated':None','name_server':'ns76.domaincontrol.com\r','status':'clientdeleteProbited',
没有一个
]})
#奇怪的是,这个错误只会在特定长度的数据集上出现
#当n为2或5时,它工作正常,但3被破坏。
df=pd.concat([df代表范围内(n)])。样品(分形=1)
打印(df.tail())
table=pa.table.from_pandas(df,preserve_index=False)
打印(表格)
#写入操作不会抛出任何错误
pq.写入表格(表格“/tmp/tst2.pa”)
#此读取是引发错误的位-这是一些随机操作错误
df=pd.read_拼花地板('/tmp/tst2.pa')
打印(df)
更新
- 我尝试过改变结构中的项数(例如,只有前两个子项),写入失败时会改变,但对于某些大小的数据,仍然会间歇性失败
- 将拼花地板版本升级到2.0
- 禁用字典写入
- 更改压缩设置
- 更改某些页面文件设置
- 使用定义模式而不是插补模式
- 取消对结构的测试(它在本例中有效,但在我的用例中无效)
pyarrow==0.17.1
python==3.6.10
pandas=1.0.5
- 这是错误、版本不匹配还是其他原因
- 如果问题在我这边,我应该如何解决
- 如果这是一个bug,我应该向谁报告?箭头开发人员?拼花地板开发者?其他人
> table.schema
whois: struct<creation_date: string, expiration_date: string, last_updated: null, name_server: string, registrar: string, status: string>
child 0, creation_date: string
child 1, expiration_date: string
child 2, last_updated: null
child 3, name_server: string
child 4, registrar: string
child 5, status: string
另一种选择是直接在pandas中展平桌子:
df = pd.DataFrame({'whois':[
{'registrar': 'GoDaddy.com, LLC', 'creation_date': '2020-07-17T16:10:35', 'expiration_date': '2022-07-17T16:10:35', 'last_updated': None, 'name_server': 'ns59.domaincontrol.com\r', 'status': 'clientDeleteProhibited'},
{'registrar': 'Hongkong Domain Name Information Management Co., Limited', 'creation_date': '2020-07-17T10:28:36', 'expiration_date': '2021-07-17T10:28:36', 'last_updated': None, 'name_server': 'ns2.alidns.com\r', 'status': 'ok'},
{'registrar': 'GoDaddy.com, LLC', 'creation_date': '2020-07-17T04:04:06', 'expiration_date': '2021-07-17T04:04:06', 'last_updated': None, 'name_server': 'ns76.domaincontrol.com\r', 'status': 'clientDeleteProhibited'},
None
]})
table = pa.Table.from_pandas(df, preserve_index=False).flatten()
df = pd.read_parquet('/tmp/tst2.pa')
df = pd.read_parquet('/tmp/tst2.pa')
作为补充说明,您可能希望提供自己的模式,因为pandas和arrow正在尝试猜测列的类型,但对于空列,它们做得不好(最后更新的是默认为float或null)
所以你可以做一些类似的事情:
df = pd.DataFrame([
{'registrar': 'GoDaddy.com, LLC', 'creation_date': '2020-07-17T16:10:35', 'expiration_date': '2022-07-17T16:10:35', 'last_updated': None, 'name_server': 'ns59.domaincontrol.com\r', 'status': 'clientDeleteProhibited'},
{'registrar': 'Hongkong Domain Name Information Management Co., Limited', 'creation_date': '2020-07-17T10:28:36', 'expiration_date': '2021-07-17T10:28:36', 'last_updated': None, 'name_server': 'ns2.alidns.com\r', 'status': 'ok'},
{'registrar': 'GoDaddy.com, LLC', 'creation_date': '2020-07-17T04:04:06', 'expiration_date': '2021-07-17T04:04:06', 'last_updated': None, 'name_server': 'ns76.domaincontrol.com\r', 'status': 'clientDeleteProhibited'},
{}
])
table_schema = pa.schema([
pa.field('creation_date', pa.string()),
pa.field('expiration_date', pa.string()),
pa.field('last_updated', pa.string()),
pa.field('name_server', pa.string()),
pa.field('registrar', pa.string()),
pa.field('status', pa.string()),
])
table = pa.Table.from_pandas(df, preserve_index=False)
pq.write_table(table, '/tmp/tst2.pa')
df = pd.read_parquet('/tmp/tst2.pa')
谢谢你的评论。几个澄清的问题:我是否误解了(特别是在这里:它说这应该是可能的?我得到了其他复杂的数据类型(例如结构列表)要工作-这里似乎还有其他事情。还有-让我觉得这些类型不受支持不是问题的是,它有时工作-它只是对不同大小的数据集失败。实际上我已经用
0.17.1
进行了测试,它对我有效。你确定你有正确版本的arrow吗?运行pa。__要检查的版本。\uuuu
。至于为什么它有时会工作,如果您的示例数据只包含空行,它应该会工作。我怀疑这就是正在发生的情况。我100%肯定我正在使用0.17.1
。为了调试特定于机器的问题,我在Google CoLab中运行了我原始问题的代码,它似乎工作得很好。所以看起来这个问题是我的机器特有的。我将用不同版本的python进行实验,并从源代码处编译arrow,看看这是否能解决它。
df = pd.DataFrame({'whois':[
{'registrar': 'GoDaddy.com, LLC', 'creation_date': '2020-07-17T16:10:35', 'expiration_date': '2022-07-17T16:10:35', 'last_updated': None, 'name_server': 'ns59.domaincontrol.com\r', 'status': 'clientDeleteProhibited'},
{'registrar': 'Hongkong Domain Name Information Management Co., Limited', 'creation_date': '2020-07-17T10:28:36', 'expiration_date': '2021-07-17T10:28:36', 'last_updated': None, 'name_server': 'ns2.alidns.com\r', 'status': 'ok'},
{'registrar': 'GoDaddy.com, LLC', 'creation_date': '2020-07-17T04:04:06', 'expiration_date': '2021-07-17T04:04:06', 'last_updated': None, 'name_server': 'ns76.domaincontrol.com\r', 'status': 'clientDeleteProhibited'},
None
]})
table = pa.Table.from_pandas(df, preserve_index=False).flatten()
df = pd.read_parquet('/tmp/tst2.pa')
df = pd.read_parquet('/tmp/tst2.pa')
> table.schema
creation_date: string
expiration_date: string
last_updated: double
name_server: string
registrar: string
status: string
df = pd.DataFrame([
{'registrar': 'GoDaddy.com, LLC', 'creation_date': '2020-07-17T16:10:35', 'expiration_date': '2022-07-17T16:10:35', 'last_updated': None, 'name_server': 'ns59.domaincontrol.com\r', 'status': 'clientDeleteProhibited'},
{'registrar': 'Hongkong Domain Name Information Management Co., Limited', 'creation_date': '2020-07-17T10:28:36', 'expiration_date': '2021-07-17T10:28:36', 'last_updated': None, 'name_server': 'ns2.alidns.com\r', 'status': 'ok'},
{'registrar': 'GoDaddy.com, LLC', 'creation_date': '2020-07-17T04:04:06', 'expiration_date': '2021-07-17T04:04:06', 'last_updated': None, 'name_server': 'ns76.domaincontrol.com\r', 'status': 'clientDeleteProhibited'},
{}
])
table_schema = pa.schema([
pa.field('creation_date', pa.string()),
pa.field('expiration_date', pa.string()),
pa.field('last_updated', pa.string()),
pa.field('name_server', pa.string()),
pa.field('registrar', pa.string()),
pa.field('status', pa.string()),
])
table = pa.Table.from_pandas(df, preserve_index=False)
pq.write_table(table, '/tmp/tst2.pa')
df = pd.read_parquet('/tmp/tst2.pa')