source

열 유형을 지정하는 판다에 빈 데이터 프레임 만들기

ittop 2023. 7. 21. 21:56
반응형

열 유형을 지정하는 판다에 빈 데이터 프레임 만들기

인덱스가 있는 빈 데이터 프레임을 만들고 열 유형을 지정하려고 합니다.제 방식은 다음과 같습니다.

df = pd.DataFrame(index=['pbp'],
                  columns=['contract',
                           'state_and_county_code',
                           'state',
                           'county',
                           'starting_membership',
                           'starting_raw_raf',
                           'enrollment_trend',
                           'projected_membership',
                           'projected_raf'],
                  dtype=['str', 'str', 'str', 'str',
                         'int', 'float', 'float',
                         'int', 'float'])

그러나 다음과 같은 오류가 발생합니다.

TypeError: data type not understood

이것은 무엇을 의미합니까?

다음을 사용할 수 있습니다.

df = pd.DataFrame({'a': pd.Series(dtype='int'),
                   'b': pd.Series(dtype='str'),
                   'c': pd.Series(dtype='float')})

또는 더 추상적으로:

df = pd.DataFrame({c: pd.Series(dtype=t) for c, t in {'a': 'int', 'b': 'str', 'c': 'float'}.items()})

사용할 경우df다음이 있습니다.

>>> df 
Empty DataFrame 
Columns: [a, b, c]
Index: []

유형을 확인하면 다음과 같습니다.

>>> df.dtypes
a      int32
b     object
c    float64
dtype: object

한 가지 방법:

import numpy
import pandas

dtypes = numpy.dtype(
    [
        ("a", str),
        ("b", int),
        ("c", float),
        ("d", numpy.datetime64),
    ]
)
df = pandas.DataFrame(numpy.empty(0, dtype=dtypes))

이것은 오래된 질문이지만, 저는 확실한 답을 보지 못합니다(@eric_g가 매우 가까웠지만).

키:값 쌍 사전을 사용하여 빈 데이터 프레임을 생성하기만 하면 됩니다.키는 열 이름이고 값은 빈 데이터 유형입니다.

따라서 예제 데이터셋에서는 다음과 같이 표시됩니다(pandas 0.25 및 python 3.7).

variables = {'contract':'',
             'state_and_county_code':'',
             'state':'',
             'county':'',
             'starting_membership':int(),
             'starting_raw_raf':float(),
             'enrollment_trend':float(),
             'projected_membership':int(),
             'projected_raf':float()}

df = pd.DataFrame(variables, index=[])

오래된 판다 버전에서는 다음을 수행해야 할 수도 있습니다.

df = pd.DataFrame(columns=[variables])

이건 정말 벌레 냄새가 납니다.

여기 또 다른 (더 간단한) 해결책이 있습니다.

import pandas as pd
import numpy as np

def df_empty(columns, dtypes, index=None):
    assert len(columns)==len(dtypes)
    df = pd.DataFrame(index=index)
    for c,d in zip(columns, dtypes):
        df[c] = pd.Series(dtype=d)
    return df

df = df_empty(['a', 'b'], dtypes=[np.int64, np.int64])
print(list(df.dtypes)) # int64, int64

인덱스를 설정하지 않고 데이터 프레임을 열 이름으로 초기화하고 다음을 사용하여 데이터 유형을 지정할 수 있습니다.astype()방법.

df = pd.DataFrame(columns=['contract',
                     'state_and_county_code',
                     'state',
                     'county',
                     'starting_membership',
                     'starting_raw_raf',
                     'enrollment_trend',
                     'projected_membership',
                     'projected_raf'])
df = df.astype( dtype={'contract' : str, 
                 'state_and_county_code': str,
                 'state': str,
                 'county': str,
                 'starting_membership': int,
                 'starting_raw_raf': float,
                 'enrollment_trend': float,
                 'projected_membership': int,
                 'projected_raf': float})

효과가 없어요, 그냥 말이에요.

다음을 사용하여 유형 오류를 해결할 수 있습니다.np.dtype:

pd.DataFrame(index = ['pbp'], columns = ['a','b'], dtype = np.dtype([('str','float')]))

대신 받을 수 있습니다.

NotImplementedError: compound dtypes are not implementedin the DataFrame constructor

저는 같은 문제에 부딪혀 이 질문을 발견했습니다.인덱스가 없는 빈 DataFrame을 만들기 위해 다음 솔루션(Python 3)을 선호합니다.

import numpy as np
import pandas as pd

def make_empty_typed_df(dtype):
    tdict = np.typeDict
    types = tuple(tdict.get(t, t) for (_, t, *__) in dtype)
    if any(t == np.void for t in types):
        raise NotImplementedError('Not Implemented for columns of type "void"')
    return pd.DataFrame.from_records(np.array([tuple(t() for t in types)], dtype=dtype)).iloc[:0, :]

테스트 중...

from itertools import chain

dtype = [('col%d' % i, t) for i, t in enumerate(chain(np.typeDict, set(np.typeDict.values())))]
dtype = [(c, t) for (c, t) in dtype if (np.typeDict.get(t, t) != np.void) and not isinstance(t, int)]

print(make_empty_typed_df(dtype))

외부:

Empty DataFrame

Columns: [col0, col6, col16, col23, col24, col25, col26, col27, col29, col30, col31, col32, col33, col34, col35, col36, col37, col38, col39, col40, col41, col42, col43, col44, col45, col46, col47, col48, col49, col50, col51, col52, col53, col54, col55, col56, col57, col58, col60, col61, col62, col63, col64, col65, col66, col67, col68, col69, col70, col71, col72, col73, col74, col75, col76, col77, col78, col79, col80, col81, col82, col83, col84, col85, col86, col87, col88, col89, col90, col91, col92, col93, col95, col96, col97, col98, col99, col100, col101, col102, col103, col104, col105, col106, col107, col108, col109, col110, col111, col112, col113, col114, col115, col117, col119, col120, col121, col122, col123, col124, ...]
Index: []

[0 rows x 146 columns]

그리고 데이터 유형은...

print(make_empty_typed_df(dtype).dtypes)

외부:

col0      timedelta64[ns]
col6               uint16
col16              uint64
col23                int8
col24     timedelta64[ns]
col25                bool
col26           complex64
col27               int64
col29             float64
col30                int8
col31             float16
col32              uint64
col33               uint8
col34              object
col35          complex128
col36               int64
col37               int16
col38               int32
col39               int32
col40             float16
col41              object
col42              uint64
col43              object
col44               int16
col45              object
col46               int64
col47               int16
col48              uint32
col49              object
col50              uint64
               ...       
col144              int32
col145               bool
col146            float64
col147     datetime64[ns]
col148             object
col149             object
col150         complex128
col151    timedelta64[ns]
col152              int32
col153              uint8
col154            float64
col156              int64
col157             uint32
col158             object
col159               int8
col160              int32
col161             uint64
col162              int16
col163             uint32
col164             object
col165     datetime64[ns]
col166            float32
col167               bool
col168            float64
col169         complex128
col170            float16
col171             object
col172             uint16
col173          complex64
col174         complex128
dtype: object

대부분의 데이터 유형에 대해 실제 결측값이 없기 때문에 인덱스를 추가하는 것이 까다로워지므로 네이티브 결측값을 가진 다른 유형(예:int에 푹 빠진.float상심한object그러나 지정한 유형의 완전한 데이터가 있는 경우 필요에 따라 언제든지 행을 삽입할 수 있으므로 유형이 유지됩니다.이는 다음을 통해 달성할 수 있습니다.

df.loc[index, :] = new_row

다시, @Hun이 지적했듯이, 이것은 판다가 어떻게 사용되도록 의도된 것이 아닙니다.

예제에서 열과 dtype을 나열하면 다음 작업을 수행할 수 있습니다.

cdt={i[0]: i[1] for i in zip(columns, dtype)}    # make column type dict
pdf=pd.DataFrame(columns=list(cdt))    # create empty dataframe
pdf=pdf.astype(cdt)                    # set desired column types

데이터 프레임 문서에서 생성자 호출에 단일 dtype만 허용된다고 합니다.

가장 쉬운 해결 방법은 각 열에 대해 비어 있는 열 목록을 연결하는 것이었습니다.

import pandas as pd

columns = ['contract',
           'state_and_county_code',
           'state',
           'county',
           'starting_membership',
           'starting_raw_raf',
           'enrollment_trend',
           'projected_membership',
           'projected_raf']
dtype = ['str', 'str', 'str', 'str', 'int', 'float', 'float', 'int', 'float']
df = pd.concat([pd.Series(name=col, dtype=dt) for col, dt in zip(columns, dtype)], axis=1)
df.info()
# <class 'pandas.core.frame.DataFrame'>
# Index: 0 entries
# Data columns (total 9 columns):
# contract                 0 non-null object
# state_and_county_code    0 non-null object
# state                    0 non-null object
# county                   0 non-null object
# starting_membership      0 non-null int32
# starting_raw_raf         0 non-null float64
# enrollment_trend         0 non-null float64
# projected_membership     0 non-null int32
# projected_raf            0 non-null float64
# dtypes: float64(3), int32(2), object(4)
# memory usage: 0.0+ bytes

사전을 DataFrame 생성자에 전달하여 이 작업을 수행할 수 있습니다.

df = pd.DataFrame(index=['pbp'],
                  data={'contract' : np.full(1, "", dtype=str),
                        'starting_membership' : np.full(1, np.nan, dtype=float),
                        'projected_membership' : np.full(1, np.nan, dtype=int)
                       }
                 )

이렇게 하면 다음과 같은 데이터 프레임이 올바르게 제공됩니다.

     contract  projected_membership   starting_membership
pbp     ""             NaN           -9223372036854775808

d 유형 포함:

contract                 object
projected_membership    float64
starting_membership       int64

즉, 다음 두 가지 사항에 유의해야 합니다.

1)str처리할 수. 인 경우인 DataFrame 열로 . 대신 일반적인 경우로 돌아갑니다.object그래도 제대로 작동할 겁니다.

왜 당신은 보지 않습니까?NaNstarting_membership 저는.NaN플로트에 는 "이 없기에 "없음"을 합니다. 정수에 대해서는 "없음" 값이 없으므로 캐스트합니다.np.NaN하려면 기본값을 변경할 수 있습니다.np.full콜.콜.

판다는 순수 정수 컬럼을 제공하지 않습니다.부동 열을 사용하고 필요에 따라 해당 열을 정수로 변환하거나 개체처럼 처리할 수 있습니다.당신이 구현하려고 하는 것은 판다가 사용되어야 하는 방식이 아닙니다.하지만 정말로 원하는 경우 이렇게 하면 TypeError 메시지를 피할 수 있습니다.

df1 =  pd.DataFrame(index=['pbp'], columns=['str1','str2','str2'], dtype=str)
df2 =  pd.DataFrame(index=['pbp'], columns=['int1','int2'], dtype=int)
df3 =  pd.DataFrame(index=['pbp'], columns=['flt1','flt2'], dtype=float)
df = pd.concat([df1, df2, df3], axis=1)

    str1 str2 str2 int1 int2  flt1  flt2
pbp  NaN  NaN  NaN  NaN  NaN   NaN   NaN

원하는 대로 색상을 다시 정렬할 수 있습니다.하지만 다시 말하지만, 이것은 판다들이 원래 사용되던 방식이 아닙니다.

 df.dtypes
str1     object
str2     object
str2     object
int1     object
int2     object
flt1    float64
flt2    float64
dtype: object

int는 개체로 처리됩니다.

다음 열 유형을 지정하여 Pandas에 빈 데이터 프레임을 만듭니다.

import pandas as pd

c1 = pd.Series(data=None, dtype='string', name='c1')
c2 = pd.Series(data=None, dtype='bool', name='c2')
c3 = pd.Series(data=None, dtype='float', name='c3')
c4 = pd.Series(data=None, dtype='int', name='c4')

df = pd.concat([c1, c2, c3, c4], axis=1)

df.info('verbose')

열을 Series(영상 시리즈)로 생성하고 올바른 dtype(dtype)을 지정한 다음 Series(영상 시리즈)를 DataFrame(데이터 프레임)으로 결합하면 끝입니다.

d타입의 데이터 프레임 생성기가 있습니다!

<class 'pandas.core.frame.DataFrame'>
Index: 0 entries
Data columns (total 4 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   c1      0 non-null      string 
 1   c2      0 non-null      bool   
 2   c3      0 non-null      float64
 3   c4      0 non-null      int32  
dtypes: bool(1), float64(1), int32(1), string(1)
memory usage: 0.0+ bytes

다음을 권장합니다.

columns = ["a", "b"]
types = ['float32', 'str']
predefined_size = 10

df = pd.DataFrame({c: pd.Series(index=range(predefined_size), dtype=t) 
                   for c,t in zip(columns, types)})

이점

  • 올드 팬더 버전 지원(예: 0.19.2)
  • 유형과 크기를 모두 초기화할 수 있습니다.

&: (테스트) & 로 초기화 & clear: 초기화여하사용를테트스초화기.numpy ndarrays

import numpy as np
import pandas as pd

df = pd.DataFrame(
    {'a': np.ndarray((0,), dtype=int),
     'b': np.ndarray((0,), dtype=str),
     'c': np.ndarray((0,), dtype=float)
     }
)
print(df.dtypes)

수확량

a      int64
b     object
c    float64
dtype: object

성능 벤치마크

이 방법은 다음에서 볼 수 있듯이 가장 빠른 방법이기도 합니다.

Python 3.8.8 (default, Apr 13 2021, 19:58:26) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.18.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import numpy as np

In [2]: import pandas as pd

In [3]: %timeit pd.DataFrame({'a': np.ndarray((0,), dtype=int), 'b': np.ndarray(
   ...: (0,), dtype=str), 'c': np.ndarray((0,), dtype=float)})

183 µs ± 388 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [4]: 

In [4]: def df_empty(columns, dtypes, index=None):
   ...:     assert len(columns)==len(dtypes)
   ...:     df = pd.DataFrame(index=index)
   ...:     for c,d in zip(columns, dtypes):
   ...:         df[c] = pd.Series(dtype=d)
   ...:     return df
   ...: %timeit df_empty(['a', 'b', 'c'], dtypes=[int, str, float])

1.14 ms ± 2.75 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [5]: 

In [5]: %timeit pd.DataFrame({'a': pd.Series(dtype='int'), 'b': pd.Series(dtype='str'), 'c': pd.Series(dtype='float')})
564 µs ± 658 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)

언급URL : https://stackoverflow.com/questions/36462257/create-empty-dataframe-in-pandas-specifying-column-types

반응형