python pandas dataframe series

python - ¿Cómo creo una nueva columna en un marco de datos a partir de una columna existente usando condiciones?



pandas dataframe (5)

Tengo una columna que contiene todos los datos que se parecen a esto (los valores que deben separarse tienen una marca como (c)):

UK (c) London Wales Liverpool US (c) Chicago New York San Francisco Seattle Australia (c) Sydney Perth

Y quiero que se divida en dos columnas con este aspecto:

London UK Wales UK Liverpool UK Chicago US New York US San Francisco US Seattle US Sydney Australia Perth Australia

Pregunta 2: ¿Qué pasaría si los países no tuvieran un patrón como (c)?


extract y ffill

Comience con extract y ffill , luego elimine las filas redundantes.

df[''country''] = ( df[''data''].str.extract(r''(.*)/s+/(c/)'', expand=False).ffill()) df[~df[''data''].str.contains(''(c)'', regex=False)].reset_index(drop=True) data country 0 London UK 1 Wales UK 2 Liverpool UK 3 Chicago US 4 New York US 5 San Francisco US 6 Seattle US 7 Sydney Australia 8 Perth Australia

Dónde,

df[''data''].str.extract(r''(.*)/s+/(c/)'', expand=False).ffill() 0 UK 1 UK 2 UK 3 UK 4 US 5 US 6 US 7 US 8 US 9 Australia 10 Australia 11 Australia Name: country, dtype: object

El patrón ''(.*)/s+/(c/)'' coincide con cadenas de la forma "country (c)" y extrae el nombre del país. Cualquier cosa que no coincida con este patrón se reemplaza con NaN, por lo que puede reenviar el relleno en las filas.

split con np.where y ffill

Esto se divide en "(c)".

u = df[''data''].str.split(r''/s+/(c/)'') df[''country''] = pd.Series(np.where(u.str.len() == 2, u.str[0], np.nan)).ffill() df[~df[''data''].str.contains(''(c)'', regex=False)].reset_index(drop=True) data country 0 London UK 1 Wales UK 2 Liverpool UK 3 Chicago US 4 New York US 5 San Francisco US 6 Seattle US 7 Sydney Australia 8 Perth Australia


Paso a paso con endswith y ffill + str.strip

df[''country'']=df.loc[df.city.str.endswith(''(c)''),''city''] df.country=df.country.ffill() df=df[df.city.ne(df.country)] df.country=df.country.str.strip(''(c)'')


Podrías hacer lo siguiente:

data = [''UK (c)'',''London'',''Wales'',''Liverpool'',''US (c)'',''Chicago'',''New York'',''San Francisco'',''Seattle'',''Australia (c)'',''Sydney'',''Perth''] df = pd.DataFrame(data, columns = [''city'']) df[''country''] = df.city.apply(lambda x : x.replace(''(c)'','''') if ''(c)'' in x else None) df.fillna(method=''ffill'', inplace=True) df = df[df[''city''].str.contains(''/(c/)'')==False]

Salida

+-----+----------------+-----------+ | | city | country | +-----+----------------+-----------+ | 1 | London | UK | | 2 | Wales | UK | | 3 | Liverpool | UK | | 5 | Chicago | US | | 6 | New York | US | | 7 | San Francisco | US | | 8 | Seattle | US | | 10 | Sydney | Australia | | 11 | Perth | Australia | +-----+----------------+-----------+


Primero puede usar str.extract para ubicar las ciudades que terminan en (c) y extraer el nombre del país, y ffill para completar una nueva columna de country .

Las mismas coincidencias extraídas se pueden usar para ubicar las filas que se deben eliminar, es decir, las filas que no son:

m = df.city.str.extract(''^(.*?)(?=/(c/)$)'') ix = m[m.squeeze().notna()].index df[''country''] = m.ffill() df.drop(ix) city country 1 London UK 2 Wales UK 3 Liverpool UK 5 Chicago US 6 New York US 7 San Francisco US 8 Seattle US 10 Sydney Australia 11 Perth Australia


Puedes usar np.where con str.contains también:

mask = df[''places''].str.contains(''(c)'', regex = False) df[''country''] = np.where(mask, df[''places''], np.nan) df[''country''] = df[''country''].str.replace(''/(c/)'', '''').ffill() df = df[~mask] df places country 1 London UK 2 Wales UK 3 Liverpool UK 5 Chicago US 6 New York US 7 San Francisco US 8 Seattle US 10 Sydney Australia 11 Perth Australia

La cadena contiene busca (c) y si está presente devolverá True para ese índice. Cuando esta condición sea Verdadera, el valor del país se agregará a las columnas del país