在没有for循环的情况下,根据另外两个系列填充系列

时间:2017-09-28 15:28:26

标签: python pandas numpy dataframe indexing

我有两个系列:s1和s2,填充一年的每小时数据。我想创建另一个系列,s3以便:

  • 如果,在特定时间内,s1> 0和s1> s2,s3 = s1
  • 如果s1> 0和s1< = s2,s3 = s2
  • 如果s1< 0,s3 = 0

所以我可以做类似

的事情
for i in range(1,len(s1)):
    if (s1.iat[i] > 0 and s1.iat[i]>s2.iat[i]):
        s3.iat[i] = s1.iat[i]
    elif (s1.iat[i] > 0 and s1.iat[i]>s2.iat[i]):
        s3.iat[i] = s2.iat[i]
    else:
        s3.iat[i] = 0

但我确信这是一种更优雅,更有希望更快的方法。我已经尝试过使用布尔索引和numpy.where的众多实现,但我不知道如何告诉Python做什么" a [b> c] = b"。它似乎不喜欢在行基础上比较不同的数组。

3 个答案:

答案 0 :(得分:2)

map(lambda a: 0 if a[0]<0 else a[0] if a[0]>a[1] else a[1],  zip(s1,s2))

这里有一些工作......

>>> s1=[-1,2,3,4,1,2,3,4]
>>> s2=[0,1,2,3,4,5,6,7]
>>> map(lambda a: 0 if a[0]<0 else a[0] if a[0]>a[1] else a[1], zip(s1,s2))
[0, 2, 3, 4, 4, 5, 6, 7]

这可能有助于解释..

>>> zip(s1,s2)
[(-1, 0), (2, 1), (3, 2), (4, 3), (1, 4), (2, 5), (3, 6), (4, 7)]

如果你采取上述措施并将其应用于你的代码......我不确定我是否会在我的最后做到这一点,因为我不知道iat是什么。

如果数组非常大,我会用zip替换itertools.izip,因为它会返回一个迭代器。

答案 1 :(得分:1)

您应该可以执行类似的操作(假设您的数组是numpy数组):

idx = (s1 > 0) & (s1 > s2)
s3[idx] = s1[idx]

idy = (s1 > 0) & (s1 <= s2)
s3[idy] = s2[idy]

idz = (s1 < 0)
s3[idz] = 0

例如:

import numpy as np
s1 = np.array([1,2,3,4,-1])
s2 = np.array([2,1,3,4,-2])

# initialize s3
s3 = np.ones(len(s1))

# do some numpy indexing magic 
idx = (s1 > 0) & (s1 > s2)
s3[idx] = s1[idx]

idy = (s1 > 0) & (s1 <= s2)
s3[idy] = s2[idy]

idz = (s1 < 0)
s3[idz] = 0

print s3
# [ 2.  2.  3.  4.  0.]

答案 2 :(得分:1)

override func viewWillAppear(_ animated: Bool) {
    self.clearsSelectionOnViewWillAppear = self.splitViewController!.isCollapsed
    super.viewWillAppear(animated)

    checkMediaAccess()
    self.setupPlaylistStore()
    tableView.reloadData()
    if store.allPlaylists.count < 1 {
        playlistTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector:     #selector(self.playlistTimerCall), userInfo: nil, repeats: true)
    }
}

@objc func playlistTimerCall() {
    self.setupPlaylistStore()
    if store.allPlaylists.count > 1 {
        tableView.reloadData()
        playlistTimer?.invalidate()
    }
}
func checkMediaAccess() {
    let authorizationStatus = MPMediaLibrary.authorizationStatus()
    switch authorizationStatus {
    case .notDetermined:
        // Show the permission prompt.
        MPMediaLibrary.requestAuthorization({[weak self] (newAuthorizationStatus: MPMediaLibraryAuthorizationStatus) in
            // Try again after the prompt is dismissed.
            self?.checkMediaAccess()
        })
    case .denied, .restricted:
        // Do not use MPMediaQuery.
        return
    default:
        // Proceed as usual.
        break
    }
}


func setupPlaylistStore() {

    // purge store
    store.clearAllPlaylists()

    // create a query of media items in playlist
    let myPlayListsQuery = MPMediaQuery.playlists()
    if myPlayListsQuery.collections != nil {
        playlists = myPlayListsQuery.collections!
    }

    // add playlists to MyPlaylist(s)
    if playlists.count > 0 {
        for index in 0...playlists.count - 1 {
            let playlist = playlists[index]
            store.addPlaylist(playlist: playlist as! MPMediaPlaylist)
        }
    }
    var toBeRemoved = [Int]()
    let defaults = UserDefaults.standard
    if defaults.bool(forKey: "exclude_smart_playlists") {
        //smart
        for index in 0...(playlists.count - 1) {
            let playlist = playlists[index]
            let theAttributes = playlist.value(forProperty: MPMediaPlaylistPropertyPlaylistAttributes) as! Int
            if theAttributes == 2 {
                toBeRemoved.append(index)
            }
        }
    }
    if defaults.bool(forKey: "exclude_folders") {
        //folders
        for index in 0...(playlists.count - 1) {
            let playlist = playlists[index]
            let isFolder = playlist.value(forProperty: "isFolder")
            let stringIsFolder = String("\(String(describing: isFolder))")
            if ((stringIsFolder.range(of: "1")) != nil) {
                toBeRemoved.append(index)
            }
        }
    }
    //sort from the last to the first so i don't reindex
    let reverseSortedPlaylists = toBeRemoved.sorted(by: >)

    // remove the unwanted playlists
    for list in reverseSortedPlaylists {
        store.removePlaylist(index: list)
    }
}