14
14
compat ,
15
15
)
16
16
import pandas ._testing as tm
17
-
17
+ import warnings
18
18
19
19
class TestToCSV :
20
20
def test_to_csv_with_single_column (self ):
@@ -741,3 +741,124 @@ def test_to_csv_iterative_compression_buffer(compression):
741
741
pd .read_csv (buffer , compression = compression , index_col = 0 ), df
742
742
)
743
743
assert not buffer .closed
744
+
745
+
746
+ def test_new_style_float_format_basic ():
747
+ df = pd .DataFrame ({"A" : [1234.56789 , 9876.54321 ]})
748
+ result = df .to_csv (float_format = "{:.2f}" )
749
+ expected = ",A\n 0,1234.57\n 1,9876.54\n "
750
+ assert result == expected
751
+
752
+ def test_new_style_float_format_thousands ():
753
+ df = pd .DataFrame ({"A" : [1234.56789 , 9876.54321 ]})
754
+ result = df .to_csv (float_format = "{:,.2f}" )
755
+ expected = ',A\n 0,"1,234.57"\n 1,"9,876.54"\n '
756
+ assert result == expected
757
+
758
+ def test_new_style_scientific_format ():
759
+ df = pd .DataFrame ({"A" : [0.000123 , 0.000456 ]})
760
+ result = df .to_csv (float_format = "{:.2e}" )
761
+ expected = ",A\n 0,1.23e-04\n 1,4.56e-04\n "
762
+ assert result == expected
763
+
764
+ def test_new_style_with_nan ():
765
+ df = pd .DataFrame ({"A" : [1.23 , np .nan , 4.56 ]})
766
+ result = df .to_csv (float_format = "{:.2f}" , na_rep = "NA" )
767
+ expected = ",A\n 0,1.23\n 1,NA\n 2,4.56\n "
768
+ assert result == expected
769
+
770
+ def test_new_style_with_mixed_types ():
771
+ df = pd .DataFrame ({"A" : [1.23 , 4.56 ], "B" : ["x" , "y" ]})
772
+ result = df .to_csv (float_format = "{:.2f}" )
773
+ expected = ",A,B\n 0,1.23,x\n 1,4.56,y\n "
774
+ assert result == expected
775
+
776
+ def test_new_style_with_mixed_types_in_column ():
777
+ df = pd .DataFrame ({"A" : [1.23 , "text" , 4.56 ]})
778
+ with warnings .catch_warnings (record = True ) as w :
779
+ warnings .simplefilter ("always" )
780
+ result = df .to_csv (float_format = "{:.2f}" )
781
+
782
+ expected = ",A\n 0,1.23\n 1,text\n 2,4.56\n "
783
+ assert result == expected
784
+
785
+ def test_invalid_new_style_format_missing_brace ():
786
+ df = pd .DataFrame ({"A" : [1.23 ]})
787
+ with pytest .raises (ValueError , match = "Invalid new-style format string '{:.2f" ):
788
+ df .to_csv (float_format = "{:.2f" )
789
+
790
+ def test_invalid_new_style_format_specifier ():
791
+ df = pd .DataFrame ({"A" : [1.23 ]})
792
+ with pytest .raises (ValueError , match = "Invalid new-style format string '{:.2z}'" ):
793
+ df .to_csv (float_format = "{:.2z}" )
794
+
795
+ def test_old_style_format_compatibility ():
796
+ df = pd .DataFrame ({"A" : [1234.56789 , 9876.54321 ]})
797
+ result = df .to_csv (float_format = "%.2f" )
798
+ expected = ",A\n 0,1234.57\n 1,9876.54\n "
799
+ assert result == expected
800
+
801
+ def test_callable_float_format_compatibility ():
802
+ df = pd .DataFrame ({"A" : [1234.56789 , 9876.54321 ]})
803
+ result = df .to_csv (float_format = lambda x : f"{ x :,.2f} " )
804
+ expected = ',A\n 0,"1,234.57"\n 1,"9,876.54"\n '
805
+ assert result == expected
806
+
807
+ def test_no_float_format ():
808
+ df = pd .DataFrame ({"A" : [1.23 , 4.56 ]})
809
+ result = df .to_csv (float_format = None )
810
+ expected = ",A\n 0,1.23\n 1,4.56\n "
811
+ assert result == expected
812
+
813
+ def test_large_numbers ():
814
+ df = pd .DataFrame ({"A" : [1e308 , 2e308 ]})
815
+ result = df .to_csv (float_format = "{:.2e}" )
816
+ expected = ",A\n 0,1.00e+308\n 1,inf\n "
817
+ assert result == expected
818
+
819
+ def test_zero_and_negative ():
820
+ df = pd .DataFrame ({"A" : [0.0 , - 1.23456 ]})
821
+ result = df .to_csv (float_format = "{:+.2f}" )
822
+ expected = ",A\n 0,+0.00\n 1,-1.23\n "
823
+ assert result == expected
824
+
825
+ def test_unicode_format ():
826
+ df = pd .DataFrame ({"A" : [1.23 , 4.56 ]})
827
+ result = df .to_csv (float_format = "{:.2f}€" , encoding = "utf-8" )
828
+ expected = ",A\n 0,1.23€\n 1,4.56€\n "
829
+ assert result == expected
830
+
831
+ def test_empty_dataframe ():
832
+ df = pd .DataFrame ({"A" : []})
833
+ result = df .to_csv (float_format = "{:.2f}" )
834
+ expected = ",A\n "
835
+ assert result == expected
836
+
837
+ def test_multi_column_float ():
838
+ df = pd .DataFrame ({"A" : [1.23 , 4.56 ], "B" : [7.89 , 0.12 ]})
839
+ result = df .to_csv (float_format = "{:.2f}" )
840
+ expected = ",A,B\n 0,1.23,7.89\n 1,4.56,0.12\n "
841
+ assert result == expected
842
+
843
+ def test_invalid_float_format_type ():
844
+ df = pd .DataFrame ({"A" : [1.23 ]})
845
+ with pytest .raises (ValueError , match = "float_format must be a string or callable" ):
846
+ df .to_csv (float_format = 123 )
847
+
848
+ def test_new_style_with_inf ():
849
+ df = pd .DataFrame ({"A" : [1.23 , np .inf , - np .inf ]})
850
+ result = df .to_csv (float_format = "{:.2f}" , na_rep = "NA" )
851
+ expected = ",A\n 0,1.23\n 1,inf\n 2,-inf\n "
852
+ assert result == expected
853
+
854
+ def test_new_style_with_precision_edge ():
855
+ df = pd .DataFrame ({"A" : [1.23456789 ]})
856
+ result = df .to_csv (float_format = "{:.10f}" )
857
+ expected = ",A\n 0,1.2345678900\n "
858
+ assert result == expected
859
+
860
+ def test_new_style_with_template ():
861
+ df = pd .DataFrame ({"A" : [1234.56789 ]})
862
+ result = df .to_csv (float_format = "Value: {:,.2f}" )
863
+ expected = ',A\n 0,"Value: 1,234.57"\n '
864
+ assert result == expected
0 commit comments