2017-10-04 10 views
1

私は、実行したいデータフレームの列のリストを持っていて、その上で操作を実行します。列はdatetimesを保持するか、何も保持しません。データテーブルの列のリストを反復しようとしています

リストの各列について、「20」を含む列のすべての値を最初の10文字にトリムします。それ以外の場合はそのままにします。

これはいくつかの方法で試しましたが、さまざまなエラーや不完全な結果が得られました。

次のバージョンでは、 '' str 'オブジェクトに属性' apply '"がありませんが、" .astype(str) "を使用しないと、" argument of type' datetime.datetime 'はiterableではありません "。

df_combined[dateColumns] = df_combined[dateColumns].fillna(notFoundText).astype(str) 
    print (dateColumns) 
    for column in dateColumns: 
     for row in range(len(column)): 
      print(df_combined[column][row]) 
      if "20" in (df_combined[column][row]): 
       df_combined[column][row].apply(lambda x: x[:10], axis=1) 
      print(df_combined[column][row]) 

ハーフ。前もって感謝します。

答えて

3

ループはパンダでは忌み嫌われているとみなされます。私はちょうどstr.contains + np.whereとこのような何かをすることをお勧めしたいと思います。

for c in df.columns: 
    # df[c] = df[c].astype(str) # uncomment this if your columns aren't dtype=str 
    df[c] = np.where(df[c].str.contains("20"), df[c].str[:10], df[c]) 
3

IIUC:

あなたが全体のデータフレームの上にこれをやってみたいです。
その場合は、データフレーム全体でnumpyを一度に使用してベクトル化します。 numpy.core.defchararray.findnp.where

from numpy.core.defchararray import find 

v = df.values.astype(str) 
i, j = np.where(find(v, '20') > -1) 

v[i, j] = v[i, j].astype('<U10') 

df.loc[:] = v 

df 

       A    B    C 
0  xxxxxxxx20 zzzzzzzzzzzzzz  wwwwwwww20 
1 kkkkkkkkkkkkkk  dddddddd20 aaaaaaaaaaaaaa 

を使用して

セットアップ

df = pd.DataFrame([ 
    ['xxxxxxxx20yyyy', 'z' * 14, 'wwwwwwww20vvvv'], 
    ['k' * 14, 'dddddddd20ffff', 'a' * 14] 
], columns=list('ABC')) 

df 

       A    B    C 
0 xxxxxxxx20yyyy zzzzzzzzzzzzzz wwwwwwww20vvvv 
1 kkkkkkkkkkkkkk dddddddd20ffff aaaaaaaaaaaaaa 

ソリューション
古いデータフレームを上書きしたくない場合は、新しいを作成することができます1:

pd.DataFrame(v, df.index, df.columns) 

       A    B    C 
0  xxxxxxxx20 zzzzzzzzzzzzzz  wwwwwwww20 
1 kkkkkkkkkkkkkk  dddddddd20 aaaaaaaaaaaaaa 
関連する問題