pandas index of data chunk

Viewed 861

I want to find the starting index and ending index of every piece of data chunk in the dataset. The data is like:

index     A  wanted_column1 wanted_column2
2000/1/1  0                    0
2000/1/2  1   2000/1/2         1
2000/1/3  1                    1
2000/1/4  1                    1
2000/1/5  0                    0
2000/1/6  1   2000/1/6         2
2000/1/7  1                    2
2000/1/8  1                    2
2000/1/9  0                    0

As shown in the data, index and A are the given columns and wanted_column1 and wanted_column2 are what I want to get. The idea is that there are different pieces of continuous chunks of data. I want to retrieve starting indices of every chunk of data and I want to increment a count of how many chunks are in the data.

I tried to use shift(-1), but it is not possible to differentiate the difference between starting index and the ending index.

2 Answers

Is that what you need ?

df['change'] = df['A'].diff().eq(1)
df['wanted_column1'] = df[['index','change']].apply(lambda x: x[0] if x[1] else None, axis=1)
df['wanted_column2'] = df['change'].cumsum()
df['wanted_column2'] = df[['wanted_column2','A']].apply(lambda x: 0 if x[1]==0 else x[0], axis=1)
df.drop('change', axis=1, inplace=True)

That yields :

    index       A   wanted_column1  wanted_column2
0   2000/1/1    0   None            0
1   2000/1/2    1   2000/1/2        1
2   2000/1/3    1   None            1
3   2000/1/4    1   None            1
4   2000/1/5    0   None            0
5   2000/1/6    1   2000/1/6        2
6   2000/1/7    1   None            2
7   2000/1/8    1   None            2
8   2000/1/9    0   None            2

Edit : performance comparison

  • gehbiszumeis's solution : 19.9 ms
  • my solution : 4.07 ms

Assuming your dataframe to be df, you can find the indices where df['A'] != 0. The indices before are the last indices of a chunck, the ones after the first ones of a chunk. Later you count the number of found indices to calculate the number of data chunks

import pandas as pd

# Read your data
df = pd.read_csv('my_txt.txt', sep=',')
df['wanted_column1'] = None     # creating already dummy columns
df['wanted_column2'] = None

# Find indices after each index, where 'A' is not 1, except of it is the last value 
#  of the dataframe
first = [x + 1 for x in df[df['A'] != 1].index.values if x != len(df)-1]
# Find indices before each index, where 'A' is not 1, except of it is the first value 
#  of the dataframe
last = [x - 1 for x in df[df['A'] != 1].index.values if x != 0]

# Set the first indices of each chunk at its corresponding position in your dataframe
df.loc[first, 'wanted_column1'] = df.loc[first, 'index']
# You can set also the last indices of each chunk (you only mentioned this in the text, 
#  not in your expected-result-listed). Uncomment for last indices.
# df.loc[last, 'wanted_column1'] = df.loc[last, 'index']   

# Count the number of chunks and fill it to wanted_column2
for i in df.index: df.loc[i, 'wanted_column2'] = sum(df.loc[:i, 'wanted_column1'].notna())
# Some polishing of the df after to match your expected result 
df.loc[df['A'] != 1, 'wanted_column2'] = 0   

This gives

      index  A wanted_column1  wanted_column2
0  2000/1/1  0           None               0
1  2000/1/2  1       2000/1/2               1
2  2000/1/3  1           None               1
3  2000/1/4  1           None               1
4  2000/1/5  0           None               0
5  2000/1/6  1       2000/1/6               2
6  2000/1/7  1           None               2
7  2000/1/8  1           None               2
8  2000/1/9  0           None               0

and works for all lengths of df and number of chunks in your data

Related