2

I have a relatively large dataframe with more than one hundred columns. Currently, only the first column was assigned a name, and the dataframe looks like:

Event 0 1 2 3 4 5 6 7 8 9 10 11 ...

I would like to rename the columns so that they look like

Event Name1 Job1 Name2 Job2 Name3 Job3 Name4 Job4 Name5 Job5 Name6 Job6 ...

Basically, for the even number columns, the names would become Name(number/2+1) and for the odd-number columns, the names would become Job((number+1)/2+1).

There was a similar question (generating column names iteratively in pandas) and I followed their method to first extract the odd columns and then assign the numbers, but the code did not really work.

I am wondering how should I do it?

Tao Han
  • 83
  • 7
  • Please add the code that *you* have tried in your question, so that it's easier for people to spot the problem. – Amir Shabani May 16 '19 at 14:40
  • I understand. It is just that the code I wrote is really messed up, and I do not really think it would be of any value...But I will keep it in mind the next time I ask a question :) – Tao Han May 16 '19 at 15:23
  • *I do not really think it would be of any value,* it **will** have value, because 1) people can see that you have tried something and you're not just asking them to write code for you. 2) It'll be much easier to solve the problem. *I will keep it in mind the next time I ask a question,* perfect! – Amir Shabani May 16 '19 at 15:27

3 Answers3

1

Here is another example:

import pandas as pd

a = {}
a["Event"] = [1,2,3]
a[0] = [1,2,3]
a[1] = [1,2,3]
a[2] = [1,2,3]
a[3] = [1,2,3]
a[4] = [1,2,3]

df = pd.DataFrame(a)

name = 1
job = 1

for i in df.keys()[1:]:
    if i%2==0:
        df = df.rename(columns={i: "Name"+str(name)})
        name+=1
    else:
        df = df.rename(columns={i: "Job"+str(job)})
        job+=1

print(df)
   Event  Name1  Job1  Name2  Job2  Name3
0      1      1     1      1     1      1
1      2      2     2      2     2      2
2      3      3     3      3     3      3
Gokhan Gerdan
  • 1,222
  • 6
  • 19
0

We must do three things:

  1. Get the list of current columns.
  2. Create a new list using the list we got from step 1.
  3. Assign the new list to columns of our DataFrame.

1:

In [1]: import pandas as pd
In [2]: df = pd.DataFrame(columns=['Event', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'])
In [3]: df
Out[3]:
Empty DataFrame
Columns: [Event, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Index: []

2:

In [4]: num_cols = len(list(df))

In [5]: num_cols
Out[5]: 13

In [6]: new_cols = []
In [7]: for i in range(num_cols):
    ...:     if i == 0:
    ...:         new_cols.append("Event")
    ...:     elif i % 2 == 0:
    ...:         new_cols.append(f'Job{int(i/2)}')
    ...:     else:
    ...:         new_cols.append(f'Name{int((i+1)/2)}')

In [8]: new_cols
Out[8]:
['Event',
 'Name1',
 'Job1',
 'Name2',
 'Job2',
 'Name3',
 'Job3',
 'Name4',
 'Job4',
 'Name5',
 'Job5',
 'Name6',
 'Job6']

3:

In [9]: df.columns = new_cols

In [10]: df
Out[10]:
Empty DataFrame
Columns: [Event, Name1, Job1, Name2, Job2, Name3, Job3, Name4, Job4, Name5, Job5, Name6, Job6]
Index: []
Amir Shabani
  • 3,857
  • 6
  • 30
  • 67
  • This is really clear. It also helps to understand some other answers I saw when reading similar questions. Many thanks! – Tao Han May 16 '19 at 15:26
  • @TaoHan Hi, is your problem solved? If so, feel free to accept an answer. – Amir Shabani May 17 '19 at 12:48
  • 1
    Hi Amir. Yes, it is solved and I did vote up but my score is too low (before 15) so the vote is not shown.... – Tao Han May 24 '19 at 15:34
  • @TaoHan You can still [accept](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) an answer. – Amir Shabani May 24 '19 at 16:49
0

How about using 2 listcomp and zip and from_iterable to flatten zip:

from itertools import chain

num_cols = 20
name = ['Name'+str(i) for i in range(1, num_cols)]
job = ['Job'+str(i)  for i in range(1, num_cols )]

df.columns = ['Event'] + list(chain.from_iterable(zip(name, job)))

Out[1918]:
['Event',
 'Name1',
 'Job1',
 'Name2',
 'Job2',
 'Name3',
 'Job3',
 'Name4',
 'Job4',
 'Name5',
 'Job5',
 'Name6',
 'Job6',
 'Name7',
 'Job7',
 'Name8',
 'Job8',
 'Name9',
 'Job9',
 'Name10',
 'Job10',
 'Name11',
 'Job11',
 'Name12',
 'Job12',
 'Name13',
 'Job13',
 'Name14',
 'Job14',
 'Name15',
 'Job15',
 'Name16',
 'Job16',
 'Name17',
 'Job17',
 'Name18',
 'Job18',
 'Name19',
 'Job19']
Andy L.
  • 24,909
  • 4
  • 17
  • 29