Create column with the same tuple value for all rows

Viewed 796

I want to create a column full of the same values. I want that value to be a tuple. Unfortunately pandas thinks I'm trying to pass in a whole column of values.

df = pd.DataFrame(index=range(10))
df['foo']=9      #ok
df['bar']=(10,12) #think's I'm passing in a too-short column

ValueError: Length of values does not match length of index

How can I set all rows of column 'bar' to be a tuple?

2 Answers

You can use DataFrame constructor:

df = pd.DataFrame({'foo': 9, 'bar':[(10,12)]}, index=range(10))

Or use list comprehension or repeat tuples by length of DataFrame:

df = pd.DataFrame(index=range(10))
df['foo']=9      #ok
df['bar']= [(10,12) for _ in df.index]
#another solution
#df['bar']= [(10,12)] * len(df)

print (df)
   foo       bar
0    9  (10, 12)
1    9  (10, 12)
2    9  (10, 12)
3    9  (10, 12)
4    9  (10, 12)
5    9  (10, 12)
6    9  (10, 12)
7    9  (10, 12)
8    9  (10, 12)
9    9  (10, 12)

Performance:

df = pd.DataFrame(index=range(1000))

In [99]: %%timeit
    ...: df['bar']='10,12'
    ...: df['bar']=df['bar'].str.split(',').astype(tuple)
    ...: 
977 µs ± 37.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [100]: %%timeit
     ...: df['bar']= [(10,12) for _ in df.index]
     ...: 
218 µs ± 3.68 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [101]: %%timeit
     ...: df['bar']= [(10,12)] * len(df)
     ...: 
175 µs ± 8.46 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [105]: %%timeit
     ...: df = pd.DataFrame({'foo': 9, 'bar':[(10,12)]}, index=range(1000))
     ...: 
400 µs ± 1.32 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [106]: %%timeit
     ...: df = pd.DataFrame(index=range(1000))
     ...: df['foo']=9
     ...: df['bar']= [(10,12)] * len(df)
     ...: 
766 µs ± 5.11 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Or you can do:

...
df['bar']='10,12'
df['bar']=df['bar'].str.split(',')

Then:

print(df)

Is:

   foo       bar
0    9  [10, 12]
1    9  [10, 12]
2    9  [10, 12]
3    9  [10, 12]
4    9  [10, 12]
5    9  [10, 12]
6    9  [10, 12]
7    9  [10, 12]
8    9  [10, 12]
9    9  [10, 12]

If want a tuple, do:

...
df['bar']='10,12'
df['bar']=df['bar'].str.split(',').map(tuple)

Now:

print(df)

Is:

   foo       bar
0    9  (10, 12)
1    9  (10, 12)
2    9  (10, 12)
3    9  (10, 12)
4    9  (10, 12)
5    9  (10, 12)
6    9  (10, 12)
7    9  (10, 12)
8    9  (10, 12)
9    9  (10, 12)
Related