Можно ли получить доступ к массиву numpy со строками?

#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 , на мой взгляд, это невозможно.