#python #arrays #numpy
#python #массивы #numpy
Вопрос:
У меня есть такая таблица:
И я хотел бы получить к нему такой доступ в python
table["Water"]["Rice"] = 3
Возможно ли это с помощью numpy.ndarray?
Комментарии:
1. Что вы имеете в виду
table
? В Python нет такого класса объектов (илиnumpy
).2. Это в основном словарь. Массивы имеют индексы, словари имеют ключи. Индексы могут быть только целыми числами, ключи могут быть любого типа. Это две разные структуры данных. Короткий ответ — нет.
3. Возможно, вы захотите попробовать pandas … в любом случае, это не совсем ясный вопрос, попробуйте добавить ввод более конкретным способом…
Ответ №1:
Предположим, что вы создали исходный массив Numpy как:
arr = np.array([[1, 3, 1],
[2, 5, 3],
[5, 6, 7]])
Но «обычные» массивы Numpy не имеют «символических» индексов (имен).
Они имеют только целочисленные индексы, начинающиеся в каждом измерении с 0.
Вы можете определить в Numpy так называемые структурированные массивы, но они допускают символьные имена только внутри строки. Такой массив состоит из строк (индексируемых целочисленным индексом), и каждая строка представляет собой набор именованных полей. Но вам нужны символьные имена как для строк, так и для столбцов, поэтому структурированные массивы Numpy вам не подходят.
На мой взгляд, единственным разумным выбором является использование фреймов данных pandasonic, где вы можете иметь символьные имена как для столбцов, так и для строк.
В Pandas:
- индекс — это набор «имен» для каждой строки,
- столбцы на самом деле также являются индексом, но содержат имена столбцов.
Чтобы создать фрейм данных из приведенного выше массива Numpy, вы можете запустить, например:
# Names of columns and rows (the same)
names = ['Water', 'Rice', 'Sauce']
# Actual creation of a DataFrame
table = pd.DataFrame(arr, index=names, columns=names)
Его содержимое:
Water Rice Sauce
Water 1 3 1
Rice 2 5 3
Sauce 5 6 7
Чтобы прочитать элемент из этого фрейма данных, вы можете использовать свой код, т.е.:
table['Water']['Rice']
В приведенном выше коде:
- Вода (первый индекс) — это имя столбца,
- Rice (второй индекс) — это индекс строки (имя),
таким образом, прочитанное значение равно 2.
Но более простой способ доступа к элементам фрейма данных:
table.loc['Water', 'Rice']
Однако на этот раз:
- Вода (первый индекс) — это индекс строки,
- Rice (второй индекс) — это имя столбца,
итак, прочитанное значение равно 3.
Вы также можете сохранить новое значение в указанной ячейке, например:
table.loc['Water', 'Rice'] = 12
Теперь, когда вы print(table)
, результат:
Water Rice Sauce
Water 1 12 1
Rice 2 5 3
Sauce 5 6 7
Если вы выполняете некоторые операции с этим фреймом данных (таблицей), но хотите затем
интегрировать его с другим кодом, ожидая работы с массивом Numpy
(не фреймом данных), вы можете передать его как:
table.values
т.е. вы передаете базовый массив Numpy.
Но тогда вы можете снова ссылаться на элементы этого массива, используя только целочисленные индексы.
Комментарии:
1. Спасибо за ваш ответ. Я наткнулся на структурированные массивы Numpy. Но не совсем понял это. Так что спасибо за объяснение. Panda выглядит интересно. Теперь я решил это другим способом. Я создал свой собственный класс «my_array», который в основном является numpy.ndarray. Я переписал » getitem » и » setitem «, чтобы найти заданную строку в словаре (string -> int) и использовать этот int для получения / сохранения значения в ndarray и его возврата. Я могу использовать этот класс так, как хотел. Но я не уверен, что это хорошее решение с точки зрения производительности. Что вы думаете?
2. Известно, что Numpy работает быстрее, чем Pandas , и это особенно важно для больших массивов. Вы можете сравнить время выполнения обеих версий, например, используя %timeit . Может быть, ваше решение будет быстрее? Попробуйте.
3. Работает ли это для массивов более высокой размерности? Например, 3D-массив.
4. К сожалению, Pandas поддерживает только 1D и 2D массивы. И мое решение «отклонилось» от первоначальной концепции использования Numpy . Таким образом, на основе Pandas , на мой взгляд, это невозможно.