Поиск строки в Dataframe, когда dataframe является как int, так и string?

#python #string #pandas #dataframe #indexing

#python #строка #панды #dataframe #индексирование

Вопрос:

небольшая проблема с моей головой. У меня есть фрейм данных, похожий на следующий:

 Number      Title
12345678    A
34567890-S  B
11111111    C
22222222-L  D
  

Это считывается из файла Excel с использованием pandas в python, затем индекс устанавливается в первый столбец:

 db = db.set_index(['Number'])
  

Затем я ищу заголовок на основе числа:

 lookup = "12345678"
title = str(db.loc[lookup, 'Title'])
  

Однако… Хотя все, что связано с «-Something», работает, все, что без него, не находит местоположение (например, 12345678 ничего не найдет, 34567890-S будет). Моя единственная догадка заключается в том, что это связано с поиском в виде строк или целых чисел, но я попробовал несколько вещей (преобразование таблицы во все строки, изменение loc на iloc, ix и т. Д.), Но пока безуспешно.

Есть идеи? Спасибо 🙂

ОБНОВЛЕНИЕ: таким образом, попытка сделать это с нуля не приводит к такому же поведению (создание тестовой базы данных, по-видимому, просто устанавливает все в виде строк), однако импорт из CSV приводит к приведенному выше, и…

Поиск «12345678» (в виде строки) не находит его, но 12345678 в качестве int будет. Аналогично обратному для других. Таким образом, dataframe сопоставляет только чистые числа в индексе с целыми числами, но все остальное со строками.

Кроме того, я не могу не искать постфикс, так как у меня есть несколько строк с разными постфиксами, например 34567890-S, 34567890-L, 34567890-X.

Комментарии:

1. Вы уверены, что у вас нет пробелов после «чисел»?

2. должно работать, если у вас нет пробелов, как упоминал @vercelli. ‘12345678’ будет работать, но ‘12345678’ не будет. Вы можете удалить индекс df.index=df.index.str.strip() , а затем loc[]

Ответ №1:

Если вы хотите привести все записи к одному определенному типу, вы можете использовать pandas.Series.astype :

 db["Number"] = df["Number"].astype(str)
db = db.set_index(['Number'])

lookup = "12345678"
title = db.loc[lookup, 'Title']
  

Интересно, что это на самом деле медленнее, чем использование pandas.Index.map :

 x1 = [pd.Series(np.arange(n)) for n in np.logspace(1, 4, dtype=int)]
x2 = [pd.Index(np.arange(n)) for n in np.logspace(1, 4, dtype=int)]

def series_astype(x1):
    return x1.astype(str)

def index_map(x2):
    return x2.map(str)
  

введите описание изображения здесь

Комментарии:

1. Спасибо, это работает. Это также сработало (после установки индекса): db.index = db.index.map(str)

2. @pepsi_max2k: добавлено сравнение времени между pandas.Series.astype и pandas.Index.map .

Ответ №2:

Рассматривайте все индексы как строки, поскольку по крайней мере некоторые из них не являются числами. Если вы хотите выполнить поиск определенного элемента, который, возможно, может иметь постфикс, вы можете сопоставить его, сравнив начало строк с .str.startswith :

 lookup = db.index.str.startswith("34567890")
title = db.loc[lookup, "Title"]