In python pandas DataFrames, what are the rules for automatic type conversion when setting values?
Question: If I have a dataframe which looks like

    
    
    import pandas
    
    d = pandas.DataFrame( data = {'col1':[100,101,102,103] } )
    #   col1
    #0   100
    #1   101
    #2   102
    #3   103
    

and I do

    
    
    d.set_value( 0,'col1', '200')
    

it casts '200' to an integer:

    
    
    type( d.col1[0] )
    #numpy.int64
    

however if I do

    
    
    d.set_value( 0,'col2', '200')
    

I get

    
    
    type( d.col2[0] )
    #str
    

as expected.

## More mysteries:

Further, say I do the following

    
    
    [ type(x) for x in d.col1 ]
    #[numpy.int64, numpy.int64, numpy.int64, numpy.int64]
    d.set_value( [0,1,2,3], 'col1', ['101', '102', '103', 200] )
    [ type(x) for x in d.col1 ]
    #[str, str, str, str]
    

So even though `d.col1` was originally an integer column, it has now become a
string column. What are the rules for such type casting of entire columns ?

I am just curious what the rules are for automatic type-casting when
manipulating pandas dataframes.


Answer: pandas is column-major and every element in the same column must have the same
data type.

When you create a dataframe using

    
    
    import pandas as pd
    df = pd.DataFrame({'col':[100,101,102,103]})
    df.col.dtype
    
    Out[11]:
    dtype('int64')
    

pandas automatically infer that all these input are numeric values and of
integer type. So when you set values for this column `col`, all your inputs
will be automatically casted into the current column `dtype` which is `int64`,
so the following will give you exactly the same output

    
    
    df.set_value(0, 'col', '200')  # cast string into int
    df.set_value(0, 'col', 200)  # int input
    df.set_value(0, 'col', 200.1)  # cast float64 into int64
    

But when you try to do `df.set_value(0, 'col1', '200')`, the current `df` has
no column `col1`, so pandas first create a new column named `col1`, and it
will try to infer the dtype for this new column based on your input.

    
    
    df.set_value(0, 'col1', '200')
    df.col1.dtype  # dtype('O'), means object/string
    df.set_value(0, 'col2', 200.1)
    df.col2.dtype  # dtype('float64')
    

