【问题标题】:Converting CSV do JSON with Pandas使用 Pandas 将 CSV 转换为 JSON
【发布时间】: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 示例相同的结构?

【问题讨论】:

    标签: python json pandas dataframe csv


    【解决方案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()
        

        【讨论】:

          猜你喜欢
          • 2018-11-06
          • 2022-01-26
          • 1970-01-01
          • 2017-09-12
          • 2017-12-17
          • 2019-03-15
          • 2020-07-01
          • 2020-02-13
          • 2021-04-26
          相关资源
          最近更新 更多