2017-02-24 59 views
0

我有一項任務是在熊貓中取一列的前6位數字。但是,如果這個數字小於6位數字,它會在數字的末尾添加一個小數。不幸的是,這對我後來的需求是不能接受的。以熊貓列的前6位數字

我敢肯定,我可以用各種代碼去掉小數,但它可能會因DataFrame變大而效率低下。

當前代碼:

import pandas as pd 
import numpy as np 
df1 = pd.DataFrame({'A' : [np.NaN,np.NaN,3,4,5,5,3,1,5,np.NaN], 
        'B' : [1,0,3,5,0,0,np.NaN,9,0,0], 
        'C' : [10,0,30,50,0,0,4,10,1,0], 
        'D' : [123456,123456,1234567,12345678,12345,12345,12345678,123456789,1234567,np.NaN], 
        'E' : ['Assign','Unassign','Assign','Ugly','Appreciate','Undo','Assign','Unicycle','Assign','Unicorn',]}) 

wow2 = df1 
wow2['D'] = wow2['D'][:6] 
print(wow2) 

    A B C  D   E 
0 NaN 1.0 10 123456  Assign 
1 NaN 0.0 0 123456 Unassign 
2 3.0 3.0 30 123456  Assign 
3 4.0 5.0 50 123456  Ugly 
4 5.0 0.0 0 12345. Appreciate <--- Notice Decimal 
5 5.0 0.0 0 12345.  Undo <--- Notice Decimal 
6 3.0 NaN 4  NaN  Assign 
7 1.0 9.0 10  NaN Unicycle 
8 5.0 0.0 1  NaN  Assign 
9 NaN 0.0 0  NaN  Unicorn 

有沒有一種方法,我可以離開數字,如果是長度不超過6?我曾考慮將列轉換爲字符串並進行循環...但我相信這會非常低效並且會產生比解決方案更多的問題

+1

你需要一個熊貓系列的前6個值或者你需要的所有值的前6位的熊貓系列?目前,您可以用'wow2 ['D'] [:6]''選擇列D的前6個值。這不會更改列中的實際值,但會將列D減少到前6個值。 – pansen

+0

@潘森...你是對的。哇,我完全錯過了。現在我唯一的想法是把它改成一個字符串:'wow2 ['D'] = wow2 ['D']。apply(str).str [:6]'但是它仍然留下小數並且將NaNs改爲字符串 – MattR

+0

您是否需要保留np.NaN值,還是應該用其他值替換它們? – pansen

回答

1

獲取數字的前6位數(不轉換爲字符串並返回),您可以使用模數operator。 爲了將您的數值表示爲非浮點數,您需要將它們轉換爲整數。但是,在同一列內混合整數和np.NaN將導致float64(有關更多信息,請參見here)。爲了解決這個問題(這很醜陋),需要將整數轉換爲強制dtype爲object的字符串,因爲您將字符串和浮點值混合在一起。

的解決方案如下所示:

wow2['D'] = wow2['D'].mod(10**6)\ 
    .dropna()\ 
    .astype(int)\ 
    .astype(str) 

print(wow['D']) 

0 123456 
1 123456 
2 234567 
3 345678 
4  12345 
5  12345 
6 345678 
7 456789 
8 234567 
9  NaN 
Name: D, dtype: object 
+0

很好的回答!謝謝!如果可能,你能解釋爲什麼'dropna()'在那裏嗎? – MattR

+0

我還注意到,如果沒有新創建的df1副本,我無法運行代碼的一部分。即使將'.copy()'添加到所有'astype()'的末尾也不起作用。任何想法爲什麼? – MattR

+0

@MattR首先,在轉換爲整數和字符串之前,dropna()用於刪除np.NaN值。否則,你將有「nan」字符串而不是np.NaN值。其次,你的*新鮮的拷貝*註釋表明你正試圖對已經改變的對象多次應用相同的操作。由於第二次使用字符串而不是數字,因此無法對列D執行兩次模運算。 – pansen