Python 熊猫读到了“忽略”;性格

Python 熊猫读到了“忽略”;性格,python,json,pandas,dataframe,csv,Python,Json,Pandas,Dataframe,Csv,我有一个CSV格式的数据帧,由字符分号(;)分隔。我的数据框中很少有JSON类型的列,我想在后面的部分将它们转换为python dict CSV file <tmp.csv>: 7.384906;7.3849072;2;0.2708226296521021;0;0;0;; 9.05233;9.05192;5;0.5523690040041611;1;0;0;"{\"EMAIL_SENT\": 1}";"{\"-1\": 1}" 3.6593602;3.6593602;2;0.546

我有一个CSV格式的数据帧,由字符分号(;)分隔。我的数据框中很少有JSON类型的列,我想在后面的部分将它们转换为python dict

CSV file <tmp.csv>:

7.384906;7.3849072;2;0.2708226296521021;0;0;0;;
9.05233;9.05192;5;0.5523690040041611;1;0;0;"{\"EMAIL_SENT\": 1}";"{\"-1\": 1}"
3.6593602;3.6593602;2;0.5465436324626254;0;0;0;;
3.5134177;3.5130887;2;0.5692996018584914;0;0;0;;
0.6824124;0.6824124;2;2.9307791611130423;0;0;0;"{\"STAGE_CHANGE\": 1, \"CREATE\": 1}";"{\"-1\": 2}"

如图所示,我的JSON列没有正确读取。我在每个JSON的开头都缺少“字符”,因此我无法将其转换为python dict

>> df[8].apply(lambda elem: {} if pd.isna(elem) else json.loads(elem))

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/anaconda3/envs/forecasting/lib/python3.7/site-packages/pandas/core/series.py", line 3848, in apply
    mapped = lib.map_infer(values, f, convert=convert_dtype)
  File "pandas/_libs/lib.pyx", line 2329, in pandas._libs.lib.map_infer
  File "<stdin>", line 1, in <lambda>
  File "/opt/anaconda3/envs/forecasting/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/opt/anaconda3/envs/forecasting/lib/python3.7/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/opt/anaconda3/envs/forecasting/lib/python3.7/json/decoder.py", line 353, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
>df[8].apply(lambda elem:{}如果pd.isna(elem)else json.loads(elem))
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/opt/anaconda3/envs/forecasting/lib/python3.7/site packages/pandas/core/series.py”,第3848行,适用于
mapped=lib.map\u推断(值,f,convert=convert\u数据类型)
文件“pandas/_libs/lib.pyx”,第2329行,在pandas中
文件“”,第1行,在
文件“/opt/anaconda3/envs/forecasting/lib/python3.7/json/_init__.py”,第348行,加载
返回\u默认\u解码器。解码
文件“/opt/anaconda3/envs/forecasting/lib/python3.7/json/decoder.py”,第337行,在decode中
obj,end=self.raw\u decode(s,idx=\u w(s,0.end())
文件“/opt/anaconda3/envs/forecast/lib/python3.7/json/decoder.py”,第353行,原始解码
obj,end=self.scan_一次(s,idx)
json.decoder.JSONDecodeError:应为包含在双引号中的属性名:第1行第2列(字符1)

请告诉我如何解决此问题。

在读取csv时使用无引号,然后在将字符串加载到json之前去掉前导/尾随双引号

df = pd.read_csv("tmp.csv", sep=";", header=None, quoting=3)
df[7].apply(lambda elem: {} if pd.isna(elem) else json.loads(elem.strip('"')))
df[8].apply(lambda elem: {} if pd.isna(elem) else json.loads(elem.strip('"')))
结果:

          0         1  2  ...  6                                 7          8
0  7.384906  7.384907  2  ...  0                                {}         {}
1  9.052330  9.051920  5  ...  0                 {'EMAIL_SENT': 1}  {'-1': 1}
2  3.659360  3.659360  2  ...  0                                {}         {}
3  3.513418  3.513089  2  ...  0                                {}         {}
4  0.682412  0.682412  2  ...  0  {'STAGE_CHANGE': 1, 'CREATE': 1}  {'-1': 2}
           0          1  2                   3  4  5  6                                     7          8
0   7.384906  7.3849072  2  0.2708226296521021  0  0  0                                    {}         {}
1    9.05233    9.05192  5  0.5523690040041611  1  0  0                     {'EMAIL_SENT': 1}  {'-1': 1}
2  3.6593602  3.6593602  2  0.5465436324626254  0  0  0                                    {}         {}
3  3.5134177  3.5130887  2  0.5692996018584914  0  0  0                                    {}         {}
4  0.6824124  0.6824124  2  2.9307791611130423  0  0  0  {'STAGE_CHANGE': 1, 'CREATE; HA': 1}  {'-1': 2}

针对json字符串包含分隔符的情况更新
我没有一个通用的解决方案,只有一个(相当难看的)示例中的解决方法。如果您知道json字符串位于最后一列中,则可以使用保证不在字符串中的分隔符将csv作为一列读取,然后拆分实数分隔符上的第一列和实数分隔符上由双引号包围的json列。从这里开始,您可以继续如前所述,只有空列是
'
,而不是
NA

例如:

df = pd.read_csv('tmp.csv', sep='\n', header=None)[0].str.split(';', 7, expand=True)
df[[7,8]] = df[7].str.split('";"|^;$', expand=True)
df[7] = df[7].apply(lambda elem: {} if elem == '' else json.loads(elem.strip('"').replace('\\"', '"')))
df[8] = df[8].apply(lambda elem: {} if elem == '' else json.loads(elem.strip('"').replace('\\"', '"')))
结果:

          0         1  2  ...  6                                 7          8
0  7.384906  7.384907  2  ...  0                                {}         {}
1  9.052330  9.051920  5  ...  0                 {'EMAIL_SENT': 1}  {'-1': 1}
2  3.659360  3.659360  2  ...  0                                {}         {}
3  3.513418  3.513089  2  ...  0                                {}         {}
4  0.682412  0.682412  2  ...  0  {'STAGE_CHANGE': 1, 'CREATE': 1}  {'-1': 2}
           0          1  2                   3  4  5  6                                     7          8
0   7.384906  7.3849072  2  0.2708226296521021  0  0  0                                    {}         {}
1    9.05233    9.05192  5  0.5523690040041611  1  0  0                     {'EMAIL_SENT': 1}  {'-1': 1}
2  3.6593602  3.6593602  2  0.5465436324626254  0  0  0                                    {}         {}
3  3.5134177  3.5130887  2  0.5692996018584914  0  0  0                                    {}         {}
4  0.6824124  0.6824124  2  2.9307791611130423  0  0  0  {'STAGE_CHANGE': 1, 'CREATE; HA': 1}  {'-1': 2}

如果字符串列中的字段具有相同的分隔符怎么办?例如,{'CREATE;HA':1}。这会将我的行拆分为超过实际列数的列。如何解决此问题?