当存在相同的名称时,使用iloc替换列

时间:2017-06-22 13:55:35

标签: python pandas indexing

假设我有以下DataFrame,其中包含一些相同的列名

test = pd.DataFrame([[1, 2, 3, np.nan, np.nan],
                     [1, 2, 3,      4,      5],
                     [1, 2, 3, np.nan, np.nan],
                     [1, 2, 3,      4, np.nan]],
                    columns=['One', 'Two', 'Three', 'Three', 'Three'])

我希望填写第四列中的NaNs。我希望能够使用iloc之类的

test.iloc[:, 3] = test.iloc[:, 3].fillna('F')

但这给出了

In [121]: test
Out[121]:
   One  Two Three Three Three
0    1    2     F     F     F
1    1    2     4     4     4
2    1    2     F     F     F
3    1    2     4     4     4

因此它会根据列名而不是位置而更改。我可以像以下一样天真地做到这一点。

c = test.columns
test.columns = range(len(test.columns))
test.iloc[:, 3] = test.iloc[:, 3].fillna('F')
test.columns = c

给出了正确的结果

In [142]: test
Out[142]:
   One  Two  Three  Three  Three
0    1    2      3      F    NaN
1    1    2      3      4    5.0
2    1    2      3      F    NaN
3    1    2      3      4    NaN

但考虑到简单的任务,似乎效率低下。

我的问题是双重的。

  • 会有更直接的方法吗?
  • 为什么第一个不起作用? (为什么iloc在替换列时仍然使用名称?)

2 个答案:

答案 0 :(得分:1)

关于第一个技术为什么不起作用的第二个问题的答案可能是因为Pandas处理重复列的方式。虽然DataFrame的构造函数没有任何设置,但read_csv documentation的参数mangle_dupe_cols的默认值为True。文档说传入False可能会导致数据覆盖。我怀疑Pandas以可疑的方式处理重复的列。

答案 1 :(得分:0)

'String tagStringForNotification = usermessageOfLast.getName(); NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(MainActivity.this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle(usermessageOfLast.getName() +"\t" + "said:") .setContentText(usermessageOfLast.getText()) .setOnlyAlertOnce(true) .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)); mBuilder.setAutoCancel(true); mBuilder.setLocalOnly(false); Intent resultIntent = new Intent(MainActivity.this, UserToUserMessageNotification.class); resultIntent.putExtra("chatsWith", tagStringForNotification); resultIntent.setAction(Long.toString(System.currentTimeMillis())); //flag to upddate current or create new one PendingIntent resultPendingIntent = PendingIntent.getActivity(MainActivity.this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT); //building the notification mBuilder.setContentIntent(resultPendingIntent); mNotificationManager.notify(tagStringForNotification, notifyID, mBuilder.build()); 正在为数据框对象建立索引,而iloc正在寻找一个系列,因此它不允许您应用fillna

更直接的是在索引它们之后直接替换NaN的值:

fillna

或者(更接近原始代码),实际选择列:

test.iloc[:,1][test.iloc[:,1].isnull()] = 'F'