Python - TypeError:'int64'类型的对象不是JSON可序列化的

时间:2018-06-18 19:39:16

标签: python pandas salesforce

我有一个存储商店名称和每日销售数量的Dataframe。我试图使用下面的Python脚本将其插入Salesforce。但是我收到了错误

  

TypeError:'int64'类型的对象不是JSON可序列化的

以下是Dataframe的视图

Storename,Count
Store A,10
Store B, 12
Store C, 5

我使用以下代码将其插入Salesforce

update_list = []
for i in range((len(store))):
    update_data = {
               'name' :    store['entity_name'].iloc[i],
                'count__c': store['count'].iloc[i] }

    update_list.append(update_data)

sf_data_cursor = sf_datapull.salesforce_login()
sf_data_cursor.bulk.Account.update(update_list)

获取上面最后一行执行的错误。谁能协助解决这个问题。感谢..

10 个答案:

答案 0 :(得分:13)

json无法识别NumPy数据类型。在序列化对象之前将数字转换为Python int

'count__c': int(store['count'].iloc[i])

答案 1 :(得分:12)

您可以定义自己的编码器来解决此问题。

import json
import numpy as np

class NpEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, np.integer):
            return int(obj)
        elif isinstance(obj, np.floating):
            return float(obj)
        elif isinstance(obj, np.ndarray):
            return obj.tolist()
        else:
            return super(NpEncoder, self).default(obj)

# Your codes .... 
json.dumps(data, cls=NpEncoder)

答案 2 :(得分:9)

我将对铃声的回答作为@Jie Yang的excellent solution的更稳定版本。

我的解决方案

numpyencoderits repository

from numpyencoder import NumpyEncoder

numpy_data = np.array([0, 1, 2, 3])

with open(json_file, 'w') as file:
    json.dump(numpy_data, file, indent=4, sort_keys=True,
              separators=(', ', ': '), ensure_ascii=False,
              cls=NumpyEncoder)

细分

如果您深入研究hmallen's文件中的numpyencoder/numpyencoder.py代码,您会发现它与@Jie Yang的答案非常相似:


class NumpyEncoder(json.JSONEncoder):
    """ Custom encoder for numpy data types """
    def default(self, obj):
        if isinstance(obj, (np.int_, np.intc, np.intp, np.int8,
                            np.int16, np.int32, np.int64, np.uint8,
                            np.uint16, np.uint32, np.uint64)):

            return int(obj)

        elif isinstance(obj, (np.float_, np.float16, np.float32, np.float64)):
            return float(obj)

        elif isinstance(obj, (np.complex_, np.complex64, np.complex128)):
            return {'real': obj.real, 'imag': obj.imag}

        elif isinstance(obj, (np.ndarray,)):
            return obj.tolist()

        elif isinstance(obj, (np.bool_)):
            return bool(obj)

        elif isinstance(obj, (np.void)): 
            return None

        return json.JSONEncoder.default(self, obj)

答案 3 :(得分:2)

另一种选择是,在创建数据框时,请使用dtype=str

例如,如果您从csv文件中加载了store

import pandas as pd
store = pd.read_csv('store.csv', dtype=str)

然后所有内容都有一种str类型,可以序列化为json。

答案 4 :(得分:1)

一个非常简单的numpy编码器可以更普遍地获得类似的结果。

请注意,这使用stimuli_words类(大多数np类都继承自该类)并使用np.generic方法。

a.item()

答案 5 :(得分:1)

如果你要序列化一个 numpy 数组,你可以简单地使用 ndarray.tolist() 方法。

来自numpy docs

<块引用>

a.tolist()list(a) 几乎相同,除了 tolist 将 numpy 标量更改为 Python 标量

In [1]: a = np.uint32([1, 2])

In [2]: type(list(a)[0])
Out[2]: numpy.uint32

In [3]: type(a.tolist()[0])
Out[3]: int

答案 6 :(得分:0)

这可能是较晚的响应,但是最近我遇到了相同的错误。经过大量的冲浪之后,此解决方案对我有所帮助。

def myconverter(obj):
        if isinstance(obj, np.integer):
            return int(obj)
        elif isinstance(obj, np.floating):
            return float(obj)
        elif isinstance(obj, np.ndarray):
            return obj.tolist()
        elif isinstance(obj, datetime.datetime):
            return obj.__str__()

通过myconverter致电json.dumps(),如下所示。 json.dumps('message', default=myconverter)

答案 7 :(得分:0)

如果你有这个错误

<块引用>

TypeError: 'int64' 类型的对象不是 JSON 可序列化的

您可以使用 int dtype 将特定列更改为 float64,例如:

import string, random, hashlib def hash_and_salt(password): password_hash = hashlib.sha256() salt = ''.join(random.choice(string.digits) for i in range (8)) password_hash.update(salt + password) return password_hash.hexdigest() , salt hash_and_salt(password="hello_world")

Float64 在 Google 电子表格中写得很好

答案 8 :(得分:0)

如果您可以控制 DataFrame 的创建,您可以通过设置 int 来强制它使用标准 Python 类型的值(例如 numpy.int64 而不是 dtype)至object

df = pd.DataFrame(data=some_your_data, dtype=object)

明显的缺点是性能低于原始数据类型。但我喜欢这个解决方案 tbh,它真的很简单并且消除了所有可能的类型问题。无需向 ORM 或 json 提供任何提示。

答案 9 :(得分:0)

我能够通过加载转储来使其工作。

代码

public static void main(String[] args) { Range<Integer> range = new Range<>(null, 5); System.out.println("range = " + range); Integer low = range.getLowerBound(); System.out.println("low = " + low); }

Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer