You could use df.filter(regex=...):

import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randn(2, 10),
                  columns='Time A_x A_y A_z B_x B_y B_z C_x C_y C-Z'.split())
X = df.filter(regex='_x')
Y = df.filter(regex='_y')

yields

In [15]: X
Out[15]: 
        A_x       B_x       C_x
0 -0.706589  1.031368 -0.950931
1  0.727826  0.879408 -0.049865

In [16]: Y
Out[16]: 
        A_y       B_y       C_y
0 -0.663647  0.635540 -0.532605
1  0.326718  0.189333 -0.803648
Answer from unutbu on Stack Overflow
🌐
datagy
datagy.io › home › pandas tutorials › pandas dataframes › python: split a pandas dataframe
Python: Split a Pandas Dataframe • datagy
December 16, 2022 - The way that you’ll learn to split a dataframe by its column values is by using the .groupby() method. I have covered this method quite a bit in this video tutorial: Let’ see how we can split the dataframe by the Name column:
Discussions

python - How to split a dataframe string column into two columns? - Stack Overflow
I have a data frame with one (string) column and I'd like to split it into two (string) columns, with one column header as 'fips' and the other 'row' My dataframe df looks like this: row ... More on stackoverflow.com
🌐 stackoverflow.com
python - Pandas split DataFrame by column value - Stack Overflow
I have DataFrame with column Sales. How can I split it into 2 based on Sales value? First DataFrame will have data with 'Sales' = s More on stackoverflow.com
🌐 stackoverflow.com
Split the pandas dataframe by a column value
Hi I have about 20 big pandas pandas data frame, each with 100,000 rows like this a b 1 0.3 1 0.5 ...... 2 3.4 ...... 2 0.4 ...... 1000 0.3 1000 4.5 where a = 1 for the first 100 rows, a = 2 for the second 100 rows, etc. Now I want to divide the dataframes into smaller ones, I tried N = 1000 ... More on discuss.python.org
🌐 discuss.python.org
1
0
March 21, 2023
python - Splitting dataframe into multiple dataframes - Stack Overflow
I would sort the dataframe by column 'name', set the index to be this and if required not drop the column. Then generate a list of all the unique entries and then you can perform a lookup using these entries and crucially if you only querying the data, use the selection criteria to return a view on the dataframe without incurring a costly data copy. Use pandas... More on stackoverflow.com
🌐 stackoverflow.com
🌐
GeeksforGeeks
geeksforgeeks.org › split-pandas-dataframe-by-column-value
Split Pandas Dataframe by column value - GeeksforGeeks
April 20, 2022 - Split Pandas DataFrame by Rows In this article, we will elucidate ... Using Pandas library, we can perform multiple operations on a DataFrame. We can even create and access the subset of a DataFrame in multiple formats. The task here is to create a subset DataFrame by column name.
🌐
Pythonfan
pythonfan.org › blog › pandas-split-dataframe-by-column-name
Pandas: Split DataFrame by Column Name | PythonFan.org
July 11, 2025 - The most straightforward way to split a DataFrame by column name is by using indexing. You can select a subset of columns using the column names and create a new DataFrame. Here is the general syntax: import pandas as pd # Assume df is your original DataFrame # Split the DataFrame by a list ...
🌐
GeeksforGeeks
geeksforgeeks.org › python › split-pandas-dataframe-by-column-index
Split Pandas Dataframe by Column Index - GeeksforGeeks
July 15, 2025 - import pandas as pd dataset = ... columns (toothed, hair, breathes, legs) for this we are going to make use of the iloc[rows, columns] method offered by pandas....
Top answer
1 of 12
834

TL;DR version:

For the simple case of:

  • I have a text column with a delimiter and I want two columns

The simplest solution is:

df[['A', 'B']] = df['AB'].str.split(' ', n=1, expand=True)

You must use expand=True if your strings have a non-uniform number of splits and you want None to replace the missing values.

Notice how, in either case, the .tolist() method is not necessary. Neither is zip().

In detail:

Andy Hayden's solution is most excellent in demonstrating the power of the str.extract() method.

But for a simple split over a known separator (like, splitting by dashes, or splitting by whitespace), the .str.split() method is enough1. It operates on a column (Series) of strings, and returns a column (Series) of lists:

>>> import pandas as pd
>>> df = pd.DataFrame({'AB': ['A1-B1', 'A2-B2']})
>>> df

      AB
0  A1-B1
1  A2-B2
>>> df['AB_split'] = df['AB'].str.split('-')
>>> df

      AB  AB_split
0  A1-B1  [A1, B1]
1  A2-B2  [A2, B2]

1: If you're unsure what the first two parameters of .str.split() do, I recommend the docs for the plain Python version of the method.

But how do you go from:

  • a column containing two-element lists

to:

  • two columns, each containing the respective element of the lists?

Well, we need to take a closer look at the .str attribute of a column.

It's a magical object that is used to collect methods that treat each element in a column as a string, and then apply the respective method in each element as efficient as possible:

>>> upper_lower_df = pd.DataFrame({"U": ["A", "B", "C"]})
>>> upper_lower_df

   U
0  A
1  B
2  C
>>> upper_lower_df["L"] = upper_lower_df["U"].str.lower()
>>> upper_lower_df

   U  L
0  A  a
1  B  b
2  C  c

But it also has an "indexing" interface for getting each element of a string by its index:

>>> df['AB'].str[0]

0    A
1    A
Name: AB, dtype: object

>>> df['AB'].str[1]

0    1
1    2
Name: AB, dtype: object

Of course, this indexing interface of .str doesn't really care if each element it's indexing is actually a string, as long as it can be indexed, so:

>>> df['AB'].str.split('-', 1).str[0]

0    A1
1    A2
Name: AB, dtype: object

>>> df['AB'].str.split('-', 1).str[1]

0    B1
1    B2
Name: AB, dtype: object

Then, it's a simple matter of taking advantage of the Python tuple unpacking of iterables to do

>>> df['A'], df['B'] = df['AB'].str.split('-', n=1).str
>>> df

      AB  AB_split   A   B
0  A1-B1  [A1, B1]  A1  B1
1  A2-B2  [A2, B2]  A2  B2

Of course, getting a DataFrame out of splitting a column of strings is so useful that the .str.split() method can do it for you with the expand=True parameter:

>>> df['AB'].str.split('-', n=1, expand=True)

    0   1
0  A1  B1
1  A2  B2

So, another way of accomplishing what we wanted is to do:

>>> df = df[['AB']]
>>> df

      AB
0  A1-B1
1  A2-B2

>>> df.join(df['AB'].str.split('-', n=1, expand=True).rename(columns={0:'A', 1:'B'}))

      AB   A   B
0  A1-B1  A1  B1
1  A2-B2  A2  B2

The expand=True version, although longer, has a distinct advantage over the tuple unpacking method. Tuple unpacking doesn't deal well with splits of different lengths:

>>> df = pd.DataFrame({'AB': ['A1-B1', 'A2-B2', 'A3-B3-C3']})
>>> df
         AB
0     A1-B1
1     A2-B2
2  A3-B3-C3
>>> df['A'], df['B'], df['C'] = df['AB'].str.split('-')
Traceback (most recent call last):
  [...]    
ValueError: Length of values does not match length of index
>>> 

But expand=True handles it nicely by placing None in the columns for which there aren't enough "splits":

>>> df.join(
...     df['AB'].str.split('-', expand=True).rename(
...         columns={0:'A', 1:'B', 2:'C'}
...     )
... )
         AB   A   B     C
0     A1-B1  A1  B1  None
1     A2-B2  A2  B2  None
2  A3-B3-C3  A3  B3    C3
2 of 12
188

There might be a better way, but this here's one approach:

                            row
    0       00000 UNITED STATES
    1             01000 ALABAMA
    2  01001 Autauga County, AL
    3  01003 Baldwin County, AL
    4  01005 Barbour County, AL
df = pd.DataFrame(df.row.str.split(' ',1).tolist(),
                                 columns = ['fips','row'])
   fips                 row
0  00000       UNITED STATES
1  01000             ALABAMA
2  01001  Autauga County, AL
3  01003  Baldwin County, AL
4  01005  Barbour County, AL
🌐
Spark By {Examples}
sparkbyexamples.com › home › pandas › split pandas dataframe by column value
Split Pandas DataFrame by Column Value - Spark By {Examples}
June 27, 2025 - The Pandas DataFrame can be split into smaller DataFrames based on either single or multiple-column values. Pandas provide various features and functions
Find elsewhere
🌐
Statology
statology.org › home › pandas: how to split dataframe by column value
Pandas: How to Split DataFrame By Column Value
November 29, 2021 - You can use the following basic syntax to split a pandas DataFrame by column value: #define value to split on x = 20 #define df1 as DataFrame where 'column_name' is >= 20 df1 = df[df['column_name'] >= x] #define df2 as DataFrame where 'column_name' ...
🌐
Hackers and Slackers
hackersandslackers.com › splitting-columns-with-pandas
Splitting Columns With Pandas
November 19, 2019 - In our original version, we told it to split on either a - or ( character. That'd work for something where we want the whole thing. In this case, though, we want to do a little cleaning as we extract - and know enough about the format that we can specify what we want to take. So, let's make a new function that instead uses the str.extract method. def assign_regex_col(df: pd.DataFrame, col: str, name_list: List[str], pat: str=None): df = df.copy() split_col = df[col].str.extract(pat, expand=True) return df.assign( **dict( zip(name_list, [split_col.iloc[:, x] for x in range(split_col.shape[1])]) ) )
🌐
Pandas
pandas.pydata.org › docs › reference › api › pandas.Series.str.split.html
pandas.Series.str.split — pandas 3.0.4 documentation - PyData |
If NaN is present, it is propagated throughout the columns during the split. >>> s.str.split(expand=True) 0 1 2 3 4 0 this is a regular sentence 1 https://docs.python.org/3/tutorial/index.html NaN NaN NaN NaN 2 NaN NaN NaN NaN NaN · For slightly more complex use cases like splitting the html document name from a url, a combination of parameter settings can be used.
🌐
Saturn Cloud
saturncloud.io › blog › how-to-split-pandas-dataframe-column-values-in-python
How to Split Pandas Dataframe Column Values in Python | Saturn Cloud Blog
May 1, 2026 - Splitting Pandas dataframe column values can be done using the split() method. The split() method splits a string into a list of strings based on a specified separator. The separator can be a single character, a string, or a regular expression.
Top answer
1 of 13
113

Can I ask why not just do it by slicing the data frame. Something like

#create some data with Names column
data = pd.DataFrame({'Names': ['Joe', 'John', 'Jasper', 'Jez'] *4, 'Ob1' : np.random.rand(16), 'Ob2' : np.random.rand(16)})

#create unique list of names
UniqueNames = data.Names.unique()

#create a data frame dictionary to store your data frames
DataFrameDict = {elem : pd.DataFrame() for elem in UniqueNames}

for key in DataFrameDict.keys():
    DataFrameDict[key] = data[:][data.Names == key]

Hey presto you have a dictionary of data frames just as (I think) you want them. Need to access one? Just enter

DataFrameDict['Joe']
2 of 13
79

Firstly your approach is inefficient because the appending to the list on a row by basis will be slow as it has to periodically grow the list when there is insufficient space for the new entry, list comprehensions are better in this respect as the size is determined up front and allocated once.

However, I think fundamentally your approach is a little wasteful as you have a dataframe already so why create a new one for each of these users?

I would sort the dataframe by column 'name', set the index to be this and if required not drop the column.

Then generate a list of all the unique entries and then you can perform a lookup using these entries and crucially if you only querying the data, use the selection criteria to return a view on the dataframe without incurring a costly data copy.

Use pandas.DataFrame.sort_values and pandas.DataFrame.set_index:

# sort the dataframe
df.sort_values(by='name', axis=1, inplace=True)

# set the index to be this and don't drop
df.set_index(keys=['name'], drop=False,inplace=True)

# get a list of names
names=df['name'].unique().tolist()

# now we can perform a lookup on a 'view' of the dataframe
joe = df.loc[df.name=='joe']

# now you can query all 'joes'
🌐
Finxter
blog.finxter.com › home › learn python blog › 5 best ways to split pandas dataframe column values
5 Best Ways to Split Pandas DataFrame Column Values - Be on the Right Side of Change
February 19, 2024 - This function splits each string by the specified delimiter and expands the result into separate columns. The expand=True parameter converts the result into a DataFrame with multiple columns.
🌐
GeeksforGeeks
geeksforgeeks.org › python › split-dataframe-in-pandas-based-on-values-in-multiple-columns
Split dataframe in Pandas based on values in multiple columns - GeeksforGeeks
July 23, 2025 - In this article, we are going to see how to divide a dataframe by various methods and based on various parameters using Python. To divide a dataframe into two or more separate dataframes based on the values present in the column we first create a data frame. ... # importing pandas as pd import pandas as pd # dictionary of lists dict = {'First_Name': ["Aparna", "Pankaj", "Sudhir", "Geeku", "Anuj", "Aman", "Madhav", "Raj", "Shruti"], 'Last_Name': ["Pandey", "Gupta", "Mishra", "Chopra", "Mishra", "Verma", "Sen", "Roy", "Agarwal"], 'Email_ID': ["apandey@gmail.com", "pankaj@gmail.com", "sumishra23@
🌐
Spark By {Examples}
sparkbyexamples.com › home › pandas › pandas split column into two columns
Pandas Split Column into Two Columns - Spark By {Examples}
November 13, 2024 - Pandas Series.str.the split() function is used to split the one-string column value into two columns based on a specified separator or delimiter. This
Top answer
1 of 2
3

Here is another way. It assumes that low/high group ends with the words Low and High respectively, so that we can use .str.endswith() to identify which rows are Low/High.

Here is the sample data

df = pd.DataFrame('group0Low group0High group1Low group1High routeLow routeHigh landmarkLow landmarkHigh'.split(), columns=['group_level'])
df

    group_level
0     group0Low
1    group0High
2     group1Low
3    group1High
4      routeLow
5     routeHigh
6   landmarkLow
7  landmarkHigh

Use np.where, we can do the following

df['level'] = np.where(df['group_level'].str.endswith('Low'), 'Low', 'High')
df['group'] = np.where(df['group_level'].str.endswith('Low'), df['group_level'].str[:-3], df['group_level'].str[:-4])

df

    group_level level     group
0     group0Low   Low    group0
1    group0High  High    group0
2     group1Low   Low    group1
3    group1High  High    group1
4      routeLow   Low     route
5     routeHigh  High     route
6   landmarkLow   Low  landmark
7  landmarkHigh  High  landmark
2 of 2
2

I suppose it depends how general the strings you're working are. Assuming the only levels are always delimited by a capital letter you can do

In [30]:    
s = pd.Series(['routeHigh', 'routeLow', 'landmarkHigh', 
               'landmarkLow', 'routeMid', 'group0Level'])
s.str.extract('([\d\w]*)([A-Z][\w\d]*)')

Out[30]:
    0       1
0   route   High
1   route   Low
2   landmark    High
3   landmark    Low
4   route   Mid
5   group0  Level

You can even name the columns of the result in the same line by doing

s.str.extract('(?P<group>[\d\w]*)(?P<Level>[A-Z][\w\d]*)')

So in your use case you can do

group_level_df = stacked.group_level.extract('(?P<group>[\d\w]*)(?P<Level>[A-Z][\w\d]*)')
stacked = pd.concat([stacked, group_level_df])

Here's another approach which assumes only knowledge of the level names in advance. Suppose you have three levels:

lower = stacked.group_level.str.lower()
for level in ['low', 'mid', 'high']:

    rows_in = lower.str.contains(level)
    stacked.loc[rows_in, 'level'] = level.capitalize()  
    stacked.loc[rows_in, 'group'] = stacked.group_level[rows_in].str.replace(level, '')

Which should work as long as the level doesn't appear in the group name as well, e.g. 'highballHigh'. In cases where group_level didn't contain any of these levels you would end up with null values in the corresponding rows