Способ POSIX
Если вы заботитесь о переносимости, используйте пример из стандарта POSIX :
i=2
end=5
while [ $i -le $end ]; do
echo $i
i=$(($i+1))
done
Выход:
2
3
4
5
Вещи, которые не POSIX:
(( ))
без доллара, хотя это общее расширение , как указано самим POSIX .[[
. [
здесь достаточно. См. Также: В чем разница между одиночными и двойными квадратными скобками в Bash? for ((;;))
seq
(GNU Coreutils) {start..end}
и не может работать с переменными, как указано в в руководстве Bash . let i=i+1
: POSIX 7 2. Язык командного командного интерпретатора не содержит слова let
, и он не работает на bash --posix
4.3.42 i=$i+1
, но я не уверен. POSIX 7 2.6.4 Арифметическое расширение гласит: если переменная оболочки x содержит значение, которое образует действительную целочисленную константу, необязательно включающую знак «плюс» или «минус», тогда арифметические разложения «$ ((x) ) "и" $ (($ x)) "должны возвращать одно и то же значение. но чтение в буквальном смысле это не означает, что $((x+1))
расширяется, поскольку x+1
не является переменной. Похоже, вы правы:
>>> import numpy
>>> import json
>>> json.dumps(numpy.int32(685))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/json/__init__.py", line 243, in dumps
return _default_encoder.encode(obj)
File "/usr/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/usr/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: 685 is not JSON serializable
Прискорбно, что число «__repr__
не дает вам никаких намеков на то, что они типа они , Они бегают, маскируясь под int
, когда их нет ( ахает ). В конечном счете, похоже, что json
говорит вам, что int
не сериализуем, но на самом деле, он говорит вам, что этот конкретный np.int32 (или любой другой тип, который у вас есть на самом деле) не сериализуем. (Ничего удивительного в этом нет - np.int32 не является сериализуемым). По этой же причине изречение, которое вы неизбежно напечатали перед передачей его в json.dumps
, выглядит так, как будто в нем тоже есть целые числа.
Самый простой обходной путь - это, вероятно, написать свой собственный сериализатор 1 sup>:
class MyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, numpy.integer):
return int(obj)
elif isinstance(obj, numpy.floating):
return float(obj)
elif isinstance(obj, numpy.ndarray):
return obj.tolist()
else:
return super(MyEncoder, self).default(obj)
Вы используете его так:
json.dumps(numpy.float32(1.2), cls=MyEncoder)
json.dumps(numpy.arange(12), cls=MyEncoder)
json.dumps({'a': numpy.int32(42)}, cls=MyEncoder)
и т.д.
1 sup> Или вы можете просто написать функцию по умолчанию и передать ее в качестве аргумента ключевого слова defaut
в json.dumps
. В этом случае вы бы заменили последнюю строку на raise TypeError
, но ... ме. Класс более расширяемый: -) sup>
Если вы оставите данные в любом из объектов pandas
, библиотека предоставит функцию to_json
для Series, DataFrame и всех других двоюродных братьев более высокого измерения.
Вы также можете преобразовать массив в список python (использовать метод tolist
), а затем преобразовать список в json.