Выберите строки в панде DataFrame, которые содержат строку, начинающуюся с целого числа - PullRequest
0 голосов
/ 14 октября 2019

Я создал DataFrame для панд, содержащий один строковый столбец. Я хочу скопировать некоторые из его строк во второй DataFrame: только строки, где символы перед первым пробелом являются целыми числами, большими или равными 300, и где символы после первого пробела являются «Бродвей». В следующем примере должна быть скопирована только первая строка.

Я бы предпочел решить эту проблему без простого написания логического выражения на прямом Python. Давайте представим, что я хотел убедить кого-то в преимуществах использования панд вместо Python без панд. Большое спасибо.


d = {
    "address": [
        "300 Broadway",      #Ok.
        "300 Wall Street",   #Sorry, not "Broadway".
        "100-10 Broadway",   #Sorry, "100-10" is not an integer.
        "299 Broadway",      #Sorry, 299 is less than 300.
        "Broadway"           #Sorry, no space at all.
    ]
}

df = pd.DataFrame(d)
df2 = df[what goes here?]   #Broadway addresses greater than or equal to 300
print(df2)

Ответы [ 2 ]

1 голос
/ 14 октября 2019

Вы можете использовать str.contains, str.extract и ge:

# rows which contain broadway
m1 = df['address'].str.contains('(?i)broadway')
# extract the numbers from the string and check if they are greater of equal to 300
m2 = df['address'].str.extract('(\d+)')[0].astype(float).ge(300)

# get all the rows which have True for both conditions
df[m1&m2]

Выход

        address
0  300 Broadway
1 голос
/ 14 октября 2019

Я думаю, что лучше всего сначала очистить данные, например:

# prepare data
df[['number', 'street']] = df.address.str.split('\s+', n=1, expand=True)
df['number'] = pd.to_numeric(df.number, errors='coerce')

Первая строка разбивает адрес на число и улицу, вторая преобразует число в действительное целое число,обратите внимание, что те значения, которые не являются целыми числами, будут преобразованы в NaN. Тогда вы можете сделать:

# create mask to filter
mask = df.number.ge(300) & df.street.str.contains("Broadway")
print(df[mask])

По сути, создать логическую маску, где число больше или равно 300, а улица равна Бродвей. Собрав все вместе, вы получите:

# prepare data
df[['number', 'street']] = df.address.str.split('\s+', n=1, expand=True)
df['number'] = pd.to_numeric(df.number, errors='coerce')

# create mask to filter
mask = df.number.eq(300) & df.street.str.contains("Broadway")
print(df[mask])

Вывод

        address  number    street
0  300 Broadway   300.0  Broadway

Обратите внимание, что это решение предполагает, что ваши данные имеют шаблон: Number Street.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...