簡體   English   中英

Pandas將列轉換為不同的dtypes

[英]Pandas Converting columns to different dtypes

所以我使用Pandas創建一個數據框,其中包含一些類型為bool,int64和date time的列。 對於較小的數據集,dtypes仍然存在,但對於較大的數據集,pandas會將所有這些轉換為對象。 誰會知道為什么它這樣做以及我如何明確設置類型呢?

閱讀CSV:

  twitterDataFrame = pandas.read_csv(DataSetLocation)

  twitterDataFrame['CreatedAt'] = twitterDataFrame['CreatedAt'].map(lambda x: pandas.to_datetime(x,dayfirst=True))
  twitterDataFrame['CreatedAtForCalculations'] = twitterDataFrame['CreatedAt']
  twitterDataFrame['InReplyToStatusID'] = twitterDataFrame['InReplyToStatusID'].map(lambda x: True if pandas.notnull(x) else False)
  twitterDataFrame['InReplyToUserID'] = twitterDataFrame['InReplyToUserID'].map(lambda x: True if pandas.notnull(x) else False)
  twitterDataFrame['RetweetCount'] = twitterDataFrame['RetweetCount'].map(lambda x: x if pandas.notnull(x) else 0)
  twitterDataFrame['FavouriteCount'] = twitterDataFrame['FavouriteCount'].map(lambda x: x if pandas.notnull(x) else 0)
  twitterDataFrame['Hashtags'] = twitterDataFrame['Hashtags'].map(lambda x: True if pandas.notnull(x) else False)
  twitterDataFrame['URL'] = twitterDataFrame['URL'].map(lambda x: True if pandas.notnull(x) else False)
  twitterDataFrame['MediaURL'] = twitterDataFrame['MediaURL'].map(lambda x: True if pandas.notnull(x) else False)
  twitterDataFrame['MediaType'] = twitterDataFrame['MediaType'].map(lambda x: x if pandas.notnull(x) else False)
  twitterDataFrame['UserMentionID'] = twitterDataFrame['UserMentionID'].map(lambda x: True if pandas.notnull(x) else False)
  twitterDataFrame['PossiblySensitive'] = twitterDataFrame['PossiblySensitive'].map(lambda x: x if pandas.notnull(x) else 'NoData')

當我打印信息時,這就是我得到的。

None
<class 'pandas.core.frame.DataFrame'>
Int64Index: 21836 entries, 0 to 21835
Data columns (total 17 columns):
CreatedAt                   21836 non-null object
ActualTweet                 21836 non-null object
InReplyToStatusID           21836 non-null bool
InReplyToUserID             21836 non-null bool
UserID                      21836 non-null object
RetweetCount                21836 non-null object
FavouriteCount              21836 non-null object
Hashtags                    21836 non-null bool
URL                         21836 non-null bool
MediaURL                    21836 non-null bool
MediaType                   21836 non-null object
UserMentionID               21836 non-null bool
PossiblySensitive           21836 non-null object
Language                    21836 non-null object
Classifier                  21836 non-null object
TweetLength                 21836 non-null object
CreatedAtForCalculations    21836 non-null object
dtypes: bool(6), object(11)None

對於較小的數據集,但是它可以正常工作,我們得到:

None
<class 'pandas.core.frame.DataFrame'>
Int64Index: 8978 entries, 0 to 8977
Data columns (total 17 columns):
CreatedAt                   8978 non-null datetime64[ns]
ActualTweet                 8978 non-null object
InReplyToStatusID           8978 non-null bool
InReplyToUserID             8978 non-null bool
UserID                      8978 non-null int64
RetweetCount                8978 non-null int64
FavouriteCount              8978 non-null int64
Hashtags                    8978 non-null bool
URL                         8978 non-null bool
MediaURL                    8978 non-null bool
MediaType                   8978 non-null object
UserMentionID               8978 non-null bool
PossiblySensitive           8978 non-null object
Language                    8978 non-null object
Trustworthy                 8978 non-null int64
TweetLength                 8978 non-null int64
CreatedAtForCalculations    8978 non-null datetime64[ns]
dtypes: bool(6), datetime64[ns](2), int64(5), object(4)None

有誰知道為什么這是我可以做些什么來解決它?

這是將現有框架的列從object為更有用的一種很好的方法。 通常你不需要這樣做,因為像read_csv這樣的東西會為你做轉換。 但是如果你有混合值,那么這些轉換可能會失敗。

請參閱此處的文檔

In [13]: data = """21-01-2014,1
   ....: 31x01x2014,foo
   ....: 01-01-2014,2
   ....: hello,3"""

In [14]: df = pd.DataFrame.from_csv( StringIO(data), index_col=None, header=None )

In [15]: df
Out[15]: 
            0    1
0  21-01-2014    1
1  31x01x2014  foo
2  01-01-2014    2
3       hello    3

In [16]: df.dtypes
Out[16]: 
0    object
1    object
dtype: object

In [17]: df.convert_objects(convert_dates='coerce',convert_numeric=True)
Out[17]: 
           0   1
0 2014-01-21   1
1        NaT NaN
2 2014-01-01   2
3        NaT   3

In [18]: df.convert_objects(convert_dates='coerce',convert_numeric=True).dtypes
Out[18]: 
0    datetime64[ns]
1           float64
dtype: object

這將轉換“看起來”像日期時間和數字的列。 您可能希望將此限制為某些列並且更具選擇性。 它只會嘗試object類型列。 此外,這是在cython中實現的,所以會非常快。

也許有更好的解決方案如何找到無法轉換的值。

這是我使用apply()解決方案

我的測試數據:

import pandas as pd
from StringIO import StringIO

data = '''21-01-2014
31x01x2014
01-01-2014
"Hello World"'''

df = pd.DataFrame.from_csv( StringIO(data), index_col=None, header=None )

print df

'''
             0
0   21-01-2014
1   31x01x2014
2   01-01-2014
3  Hello World
'''

我創建函數使用datetime.datetime.strptime()try/except來捕獲(並打印)不正確的日期。

from datetime import datetime

def test_datetime(x):
    try:
        datetime.strptime(x, "%d-%M-%Y")
    except:
        print 'incorect:', x

然后我可以使用apply()來測試列中的所有值

df[0].apply(test_datetime)

'''
incorect: 31x01x2014
incorect: Hello World
'''

但是我可以在之前的函數中添加return True/False

from datetime import datetime

def test_datetime(x):
    try:
        datetime.strptime(x, "%d-%M-%Y")
        return False
    except:
        return True

以這種方式使用它並獲取索引數據

print df[ df[0].apply(test_datetime) ]

'''
             0
1   31x01x2014
3  Hello World
'''

並在此行上運行其他功能

df[ df[0].apply(test_datetime) ] = '01-01-2000'

print df

'''
            0
0  21-01-2014
1  01-01-2000
2  01-01-2014
3  01-01-2000
'''

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM