如何以附加模式导出 DataFrame to_json - Python Pandas?

Posted

技术标签:

【中文标题】如何以附加模式导出 DataFrame to_json - Python Pandas?【英文标题】:How to export DataFrame to_json in append mode - Python Pandas? 【发布时间】:2015-07-25 12:15:55 【问题描述】:

我有一个字典列表格式的现有 json 文件。

$cat output.json
['a':1, 'b':2, 'a':2, 'b':3]

我有一个数据框

df = pd.DataFrame('a':pd.Series([1,2], index=list('CD')), \
              "b":pd.Series([3,4], index=list('CD'))

我想用 to_json 保存“df”以将其附加到文件 output.json:

df.to_json('output.json', orient='records')  #  mode='a' not available for to_json

* to_csv 有 append mode='a',但 to_json 没有。

预期生成的 output.json 文件将是:

    ['a':1, 'b':2, 'a':2, 'b':3, 'a':1, 'b':3, 'a':2, 'b':4]

现有文件 output.json 可能很大(比如 TB),是否可以在不加载文件的情况下附加新的数据帧结果?

http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.to_json.html http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.to_csv.html

【问题讨论】:

【参考方案1】:

不,如果不使用pandasjson 模块重写整个文件,您就无法附加到json 文件。您可以通过在a 模式下打开文件并寻找正确的位置并插入数据来“手动”修改文件。我不会推荐这个。如果您的文件比 RAM 大,最好只使用 json 以外的文件格式。

这个answer 也可能有帮助。它不会创建有效的 json 文件(而是每一行都是一个 json 字符串),但它的目标与你的非常相似。

【讨论】:

【参考方案2】:

您可能需要考虑orient='records'

def to_json_append(df,file):
    '''
    Load the file with
    pd.read_json(file,orient='records',lines=True)
    '''
    df.to_json('tmp.json',orient='records',lines=True)
    #append
    f=open('tmp.json','r')
    k=f.read()
    f.close()
    f=open(file,'a')
    f.write('\n') #Prepare next data entry
    f.write(k)
    f.close()

df=pd.read_json('output.json')
#Save again as lines
df.to_json('output.json',orient='records',lines=True)
#new data
df = pd.DataFrame('a':pd.Series([1,2], index=list('CD')), \
              "b":pd.Series([3,4], index=list('CD'))
#append:
to_json_append(df,'output.json')

加载完整数据

pd.read_json('output.json',orient='records',lines=True)

【讨论】:

【参考方案3】:

我已经通过使用内置的 pandas.DataFrame 方法解决了这个问题。您需要记住大型数据帧的性能(有处理它的方法)。 代码:

if os.path.isfile(dir_to_json_file):
    # if exist open read it
    df_read = pd.read_json(dir_to_json_file, orient='index')
    # add data that you want to save
    df_read = pd.concat([df_read, df_to_append], ignore_index=True)
    # in case of adding to much unnecessery data (if you need)
    df_read.drop_duplicates(inplace=True)

    # save it to json file in AppData.bin
    df_read.to_json(dir_to_json_file, orient='index')
else:
    df_to_append.to_json(dir_to_json_file, orient='index')

【讨论】:

【参考方案4】:

用例,将大量数据写入小内存的JSON文件:

假设我们有 1,000 个数据帧,每个数据帧就像 1000,000 行 json。每个数据帧需要 100MB,总文件大小为 1000 * 100MB = 100GB。

解决方案:

    使用缓冲区存储每个数据帧的内容 使用 pandas 将其转储为文本 使用追加模式将文本写入文件末尾
import io
import pandas as pd
from pathlib_mate import Path

n_lines_per_df = 10
n_df = 3
columns = ["id", "value"]
value = "alice@example.com"
f = Path(__file__).change(new_basename="big-json-file.json")
if not f.exists():
    for nth_df in range(n_df):
        data = list()
        for nth_line in range(nth_df * n_lines_per_df, (nth_df + 1) * n_lines_per_df):
            data.append((nth_line, value))
        df = pd.DataFrame(data, columns=columns)
        buffer = io.StringIO()
        df.to_json(
            buffer,
            orient="records",
            lines=True,
        )
        with open(f.abspath, "a") as file:
            file.write(buffer.getvalue())

【讨论】:

以上是关于如何以附加模式导出 DataFrame to_json - Python Pandas?的主要内容,如果未能解决你的问题,请参考以下文章

将 numpy 数组转换为 pyspark 中的 DataFrame 以导出为 csv

如何附加到包含时间序列的 DataFrame 中的列

vuex文档(附加个人理解)

将dict动态附加到空的Pandas.Dataframe中[重复]

Python Pandas Dataframe:如何同时将多个索引附加到列表中?

如何将 Python 字典附加到 Pandas DataFrame,将键与列名匹配