У меня есть фрейм данных с разными адресами.
И мне нужно разделить столбец «Адрес» на несколько столбцов, чтобы каждый элемент строки находился в правильном столбце, например:
Не могли бы вы помочь с этим?
ну, первые три элемента всегда — это страна, штат и город. других можно определить по таким словам, как «район», «улица» и т. д.
@lzvtmtvv Хорошо, тогда отредактируйте вопрос, добавив эти критерии. Это часть вопроса.






import pandas as pd
# Minimal reproducible example (that the way you should have given it, fyi :))
df=pd.DataFrame({'Address': ['USA, Utah, Richfield, building 315E', 'Russia, Moscow oblast, Moscow, Arbat District, New street, building 78']})
# Easy part, get country, region, city
splitAddress = df['Address'].str.split(',')
df[['Country', 'Region', 'City']] = splitAddress.str[:3].tolist()
rest = splitAddress.str[3:]
# District, if there is one, should be in first item of unused elements
m=(rest.str.len()>0) & (rest.str[0].str.contains('District'))
df.loc[m, 'District'] = rest[m].str[0]
rest[m]=rest[m].str[1:]
# Street, if there is one, should be the first remaining
m=(rest.str.len()>0) & (rest.str[0].str.contains('street'))
df.loc[m, 'Street'] = rest[m].str[0]
rest[m]=rest[m].str[1:]
# What remains is the rest of address
# WE could just assume that there is only one field left (at most) as in your example. But just in case, rejoin rest
m=rest.str.len()>0
df.loc[m, 'Building'] = rest[m].str.join(', ')
Я предполагаю, что требуется некоторая настройка. Мое обнаружение того, что такое район (часть, содержащая слово «Район», с учетом регистра и ничего больше), улица (часть, содержащая слово «улица», с учетом регистра и ничего больше) и здание (независимо от того, что не является районом или улица), вероятно, нуждается в более тщательном тесте. Но судя по тем немногим указаниям, которые вы дали... Плюс оттуда вы сможете добавлять критерии.
Кроме того, вообще говоря, параметр expand=True в split (который использовался в кратком ответе, который теперь исчез), вероятно, является лучшим способом разбить строку на столбцы. Я не использовал его, потому что не знаю, как сохранить только 3, а затем, как сделать с ним мою часть «фильтрация первого элемента отдыха, удаление того, что я использую». Но, возможно, есть способ (я не «панда-гуру», поэтому есть много однострочного кода, который я пишу в несколько строк). Но дело в том, что у меня нет ни for, ни apply, ни чего-либо, что делало бы часть итерации чистым Python. Таким образом, даже если могут быть более быстрые решения (может быть даже в два или в 3 раза быстрее), они должны быть одного порядка скорости (не что иное, как фактор ×1000, который мы наблюдаем, когда for или некоторые apply/map удалены)
Альтернативный подход, который инициализирует список со значениями None.
import pandas as pd
columns_order = ['Country', 'Region/State', 'City', 'District', 'Street', 'Building']
df = pd.DataFrame({'Address': datas})
def split_address(address):
parts = address.split(', ')
num_nones = len(columns_order) - len(parts)
ordered_parts = parts + [None] * num_nones
return pd.Series(ordered_parts, index=columns_order)
res = df['Address'].apply(split_address)
Вероятно, вы можете попробовать регулярное выражение:
import re
pat = (r'(?P<Country>[^,]+),\s*'
r'(?P<State>[^,]+),\s*'
r'(?P<City>[^,]+)'
r'(?:,\s*(?P<District>.*district[^,]*))?'
r'(?:,\s*(?P<Street>.*street[^,]*))?'
r'(?:,\s*(?P<Building>.*building.*))?')
ADDRESS = re.compile(pat, re.IGNORECASE)
out = df['Address'].str.extract(ADDRESS)
Выход:
>>> out
Country State City District Street Building
0 USA Utah Richfield NaN NaN building 315E
1 Russia Moscow oblast Moscow Arbat District New street building 78
Демо на Regex101
Какую логику можно применить, чтобы связать части строки с определенными столбцами?