Question: This script:

```
import numpy as np
import pandas as pd

#

x = 10000 * np.pi

df = pd.DataFrame({"test": [x]})

df.to_csv("pd_test.csv")

other_df = pd.read_csv("pd_test.csv")

print(df["test"][0], other_df["test"][0])
print(df["test"][0] - other_df["test"][0])

```

Gives:

```
31415.926535897932 31415.92653589793
3.637978807091713e-12

```

I would like to not introduce a change when saving and loading to CSV, if possible - for example, is there a datatype I can use for the dataframe which would accomplish this?

I don't mind losing a small amount of accuracy if necessary, I would just like to avoid the change during the save and load process if possible.

Answer: 
Can you use `@Immutable(copyWith = true)`

```
@Immutable(copyWith = true)
class Person {
    String first, last
}

def tim   = new Person('tim', 'yates')
def alice = tim.copyWith(first:'alice')

assert tim.first   == 'tim'
assert alice.first == 'alice'

```

<https://docs.groovy-lang.org/latest/html/gapi/groovy/transform/ImmutableBase.html#copyWith>
There are many ways this can be done.

One is to construct instances by spreading in a map, e.g., given:

```
class Person { String name; Boolean isHuman; }

```

An instance can be constructed using the same spread-map operator I linked to:

```
m1 = [ name: "Gabe", isHuman: true ]
p1 = new Person(*:m1)
println p1
// Person: Gabe, isHuman=true

```

This avoids actual work. An exception will be thrown if a map key isn't an instance property.

A utility method grabbing *(non-synthetic)* prop names from a class, and iterates while putting the name/value pairs into a map is also an option *(and affords a bit more safety)*:

```
def toMap(obj) {
  obj.class.declaredFields
    .findAll { !it.synthetic }
    .collectEntries { [(it.name): obj."$it.name" ] }
}

```

Now we can construct a "prototype" object, but override properties:

```
p2 = new Person(*:toMap(p1), name: "Alice")
println p2
// Person: Alice, isHuman=true

```

There are also libraries that do this type of work.

Depending on your *actual* usecase it may not be necessary to do anything other than passing a map, however (duck typing).