pandas set_levels,如何避免标签的排序?

时间:2018-01-02 12:39:11

标签: python pandas multi-index

我使用多索引的from io import StringIO txt = '''Name,Height,Age "",Metres,"" A,-1,25 B,95,-1''' df = pd.read_csv(StringIO(txt),header=[0,1],na_values=['-1','']) df.columns = df.columns.set_levels(df.columns.get_level_values(level=1).str.replace('Un.*',''),level=1) Name Height Age Metres 0 A NaN 25.0 1 B 95.0 NaN

遇到了问题
df.columns = df.columns.set_levels(df.columns.get_level_values(level=1).str.replace('Un.*',''),level=1)

  Name Height   Age
       Metres      
0    A    NaN  25.0
1    B   95.0   NaN

如果我再次运行相同的命令

import { Component, ViewChild, ElementRef } from '@angular/core';
import { NavController, ViewController, NavParams, LoadingController, AlertController } from 'ionic-angular';
import { AppConfig } from '../../app/app-config';
import { SowService } from '../../providers/sow-service';
import { TbarService } from '../../providers/tbar-service';
import { TranslateService } from '@ngx-translate/core';
import { Geolocation } from '@ionic-native/geolocation';

declare var google;

@Component({
    selector: 'map-page',
    templateUrl: 'map.html'
})
export class MapPage {

    @ViewChild('map') mapElement: ElementRef;
    map: any;

    vendors: any;

    constructor(public navCtrl: NavController, public viewCtrl: ViewController, public appConfig: AppConfig, public geolocation: Geolocation,
        public navParams: NavParams, public sowService: SowService, public tb: TbarService, public loadingCtrl: LoadingController,
        public alertCtrl: AlertController, public translateService: TranslateService) { }

    ionViewDidEnter() {
        this.translateService.get(['Notice', 'Loading', 'NetWork_Error', 'OK']).subscribe(value => {
            var loadingModal = this.loadingCtrl.create({
                content: value['Loading']
            });
            loadingModal.present();
            this.sowService.getVendorList().then((data) => {
                this.vendors = data;
                loadingModal.dismiss();
            }, (reson) => {
                loadingModal.dismiss();
                this.alertCtrl.create({
                    title: value['Notice'],
                    message: value['NetWork_Error'],
                    buttons: [value['OK']]
                });
            });
        });

    }

    ionViewDidLoad() {
        this.loadMap();
    }

    loadMap() {

        this.geolocation.getCurrentPosition().then((position) => {

            let latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

            let mapOptions = {
                center: latLng,
                zoom: 15,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            }

            this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
            this.map = this.addMarker();

        },(err) => {
            console.log(err);
        });
    }

    addMarker() {

        let marker = new google.maps.Marker({
            map: this.map,
            animation: google.maps.Animation.DROP,
            position: this.map.getCenter()
        });

        let content = "<h4>" + this.vendor.shop_name + "</h4>";

        this.addInfoWindow(marker, content);

    }

    addInfoWindow(marker, content) {

        let infoWindow = new google.maps.InfoWindow({
            content: content
        });

        google.maps.event.addListener(marker, 'click', () => {
            infoWindow.open(this.map, marker);
        });

    }
}

现在这产生了预期的结果。为什么会出现这种情况?是否可以在第一次尝试时保持标签不分类?

2 个答案:

答案 0 :(得分:2)

我不完全理解为什么会发生这种情况,但我找到了导致问题的原因和解决方案:

如果我们查看列标签,我们可以看到奇怪的东西

>>> df = pd.read_csv(StringIO(txt),header=[0,1],na_values=['-1',''])
>>> df.columns
MultiIndex(levels=[['Age', 'Height', 'Name'], ['Metres', 'Unnamed: 0_level_1', 'Unnamed: 2_level_1']],
           labels=[[2, 1, 0], [1, 0, 2]])

第二级的索引与第一层的索引不匹配。当您替换字符串时,您在正确顺序的数组上执行此操作:

>>> df.columns.get_level_values(level=1)
Index(['Unnamed: 0_level_1', 'Metres', 'Unnamed: 2_level_1'], dtype='object')

但是你可以通过编制索引来获取不正确的顺序中的数组:

>>> df.columns.levels[1]
Index(['Metres', 'Unnamed: 0_level_1', 'Unnamed: 2_level_1'], dtype='object')

所以要删除未命名的索引:

>>> df.columns = df.columns.set_levels(df.columns.levels[1].str.replace('Un.*', ''), level=1)
>>> df

  Name Height   Age
       Metres
0    A    NaN  25.0
1    B   95.0   NaN

但是我希望有人指出为什么使用get_set_levels有这种行为。

答案 1 :(得分:1)

听起来像你需要的,这会根据你的原始结构进行修改

df.rename(columns=lambda x : '' if 'Unnamed' in x else x , level=1)
Out[106]: 
  Name Height   Age
       Metres      
0    A    NaN  25.0
1    B   95.0   NaN