使用 Pandas 将 CSV 转换为 JSON
Posted
技术标签:
【中文标题】使用 Pandas 将 CSV 转换为 JSON【英文标题】:Converting CSV do JSON with Pandas 【发布时间】:2021-12-28 16:53:55 【问题描述】:我有CSV格式的数据,例如:
第一行是列号,我们忽略它。 第二行,从 Col_4 开始,是天数 第三行:Col_1 和 Col_2 是坐标(经度、纬度),Col_3 是统计值,Col_4 以后是测量值。如您所见,这种格式令人困惑。我想通过以下方式将其转换为 JSON,例如:
"points":
"dates": ["20190103", "20190205"],
"0":
"lon": "-8.072557",
"lat": "41.13702",
"measurements": ["-0.191792","-10.543130"],
"val": "-1"
,
"1":
"lon": "-8.075557",
"lat": "41.15702",
"measurements": ["-1.191792","-2.543130"],
"val": "-9"
总结一下我到目前为止所做的事情,我将 CSV 读取到 Pandas DataFrame:
df = pandas.read_csv("sample.csv")
我可以将日期提取到一个 Numpy 数组中:
dates = df.iloc[0][3:].to_numpy()
我可以提取所有点的测量值:
measurements_all = df.iloc[1:,3:].to_numpy()
而 lon 和 lat 和 val 分别用:
lon_all = df.iloc[1:,0:1].to_numpy()
lat_all = df.iloc[1:,1:2].to_numpy()
val_all = df.iloc[1:,2:3].to_numpy()
谁能解释我如何将此信息格式化为与 .json 示例相同的结构?
【问题讨论】:
【参考方案1】:有了这个数据框
df = pd.DataFrame(["col1": 1, "col2": 2, "col3": 3, "col4":3, "col5":5,
"col1": None, "col2": None, "col3": None, "col4":20190103, "col5":20190205,
"col1": -8.072557, "col2": 41.13702, "col3": -1, "col4":-0.191792, "col5":-10.543130,
"col1": -8.072557, "col2": 41.15702, "col3": -9, "col4":-0.191792, "col5":-2.543130])
此代码执行您想要的操作,尽管它没有像您的示例那样将任何内容转换为字符串。但如有必要,您应该能够轻松地做到这一点。
# generate dict with dates
final_dict = "dates": [list(df["col4"])[1],list(df["col5"])[1]]
# iterate over relevant rows and generate dicts
for i in range(2,len(df)):
final_dict[i-2] = "lon": df["col1"][i],
"lat": df["col2"][i],
"measurements": [df[cname][i] for cname in ["col4", "col5"]],
"val": df["col3"][i]
这导致这个输出:
0: 'lat': 41.13702,
'lon': -8.072557,
'measurements': [-0.191792, -10.54313],
'val': -1.0,
1: 'lat': 41.15702,
'lon': -8.072557,
'measurements': [-0.191792, -2.54313],
'val': -9.0,
'dates': [20190103.0, 20190205.0]
【讨论】:
【参考方案2】:从数据中提取日期,然后从数据框中删除第一行:
dates =list(data.iloc[0][3:])
data=data.iloc[1:]
将日期插入到字典中:
points="dates":dates
遍历数据框并将元素添加到字典中:
i=0
for index, row in data.iterrows():
element= "lon":row["Col_1"],
"lat":row["Col_2"],
"measurements": [row["Col_3"], row["Col_4"]]
points[str(i)]=element
i+=1
您可以使用 json.dumps() 将 dict 转换为字符串对象:
points_json = json.dumps(points)
它将是字符串对象,而不是 json(dict) 对象。更多关于这个的帖子Converting dictionary to JSON
【讨论】:
【参考方案3】:我将 pandas 数据框的值转换为一个列表,然后遍历其中一个列表,并将这些列表添加到包含这些值的嵌套 JSON 对象中。
import pandas
import json
import argparse
import sys
def parseInput():
parser = argparse.ArgumentParser(description="Convert CSV measurements to JSON")
parser.add_argument(
'-i', "--input",
help="CSV input",
required=True,
type=argparse.FileType('r')
)
parser.add_argument(
'-o', "--output",
help="JSON output",
type=argparse.FileType('w'),
default=sys.stdout
)
return parser.parse_args()
def main():
args = parseInput()
input_file = args.input
output = args.output
dataframe = pandas.read_csv(input_file)
longitudes = dataframe.iloc[1:,0:1].T.values.tolist()[0]
latitudes = dataframe.iloc[1:,1:2].T.values.tolist()[0]
averages = dataframe.iloc[1:,2:3].T.values.tolist()[0]
measurements = dataframe.iloc[1:,3:].values.tolist()
dates=dataframe.iloc[0][3:].values.tolist()
points="dates":dates
for index, val in enumerate(longitudes):
entry =
"lon":longitudes[index],
"lat":latitudes[index],
"measurements":measurements[index],
"average":averages[index]
points[str(index)] = entry
json.dump(points, output)
if __name__ == "__main__":
main()
【讨论】:
以上是关于使用 Pandas 将 CSV 转换为 JSON的主要内容,如果未能解决你的问题,请参考以下文章
Python Pandas 使用 Fastparquet 将 CSV 转换为 Parquet
如何使用 python 和 pandas 将 Csv 文件转换为 libsvm?
使用 python pandas 将 json 转换为 csv