Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在Pandas中指定单元格值的最快方法_Python_Pandas_Numpy - Fatal编程技术网

Python 在Pandas中指定单元格值的最快方法

Python 在Pandas中指定单元格值的最快方法,python,pandas,numpy,Python,Pandas,Numpy,我有一个元组列表: d = [("a", "x"), ("b", "y"), ("a", "y")] 以及数据帧: y x b 0.0 0.0 a 0.0 0.0 如果行和列标签对应于d中的元组,则我想将任何0s替换为1s,这样新的数据帧是: y x b 1.0 0.0 a 1.0 1.0 我目前正在使用: for i, j in d: df.loc[i, j] = 1.0 在我看来,这似乎是最“pythonic”的方法,但对于形状

我有一个元组列表:

d = [("a", "x"), ("b", "y"), ("a", "y")]
以及
数据帧

     y    x
b  0.0  0.0
a  0.0  0.0
如果行和列标签对应于
d
中的元组,则我想将任何
0s
替换为
1s
,这样新的数据帧是:

     y    x
b  1.0  0.0
a  1.0  1.0
我目前正在使用:

for i, j in d:
    df.loc[i, j] = 1.0
在我看来,这似乎是最“pythonic”的方法,但对于形状为20000*20000的
DataFrame
和长度为10000的列表,这一过程实际上需要永远的时间。必须有更好的方法来实现这一点。有什么想法吗

感谢与
数据帧一起使用
构造函数:

df = pd.get_dummies(pd.DataFrame(d).set_index(0)[1]).rename_axis(None).max(level=0)
或者将
zip
系列一起使用:

lst = list(zip(*d))
df = pd.get_dummies(pd.Series(lst[1], index = lst[0])).max(level=0)

方法#1:d
d

这里有一个基于NumPy的方法-

def assign_val(df, d, newval=1):    
    # Get d-rows,cols as arrays for efficient usage latet on
    di,dc = np.array([j[0]  for j in d]), np.array([j[1]  for j in d])

    # Get col and index data
    i,c = df.index.values.astype(di.dtype),df.columns.values.astype(dc.dtype)

    # Locate row indexes from d back to df
    sidx_i = i.argsort()
    I = sidx_i[np.searchsorted(i,di,sorter=sidx_i)]

    # Locate column indexes from d back to df
    sidx_c = c.argsort()
    C = sidx_c[np.searchsorted(c,dc,sorter=sidx_c)]

    # Assign into array data with new values
    df.values[I,C] = newval
    # Use df.to_numpy(copy=False)[I,C] = newval on newer pandas versions
    return df
样本运行-

In [21]: df = pd.DataFrame(np.zeros((2,2)), columns=['y','x'], index=['b','a'])

In [22]: d = [("a", "x"), ("b", "y"), ('a','y')]

In [23]: assign_val(df, d, newval=1)
Out[23]: 
     y    x
b  1.0  0.0
a  1.0  1.0
方法#2:通用方法

如果'd'中有任何不正确的条目,我们需要过滤掉这些条目。因此,对于一般情况,修改后的-

def ssidx(i,di):
    sidx_i = i.argsort()
    idx_i = np.searchsorted(i,di,sorter=sidx_i)
    invalid_mask = idx_i==len(sidx_i)
    idx_i[invalid_mask] = 0
    I = sidx_i[idx_i]    
    invalid_mask |= i[I]!=di
    return I,invalid_mask

# Get d-rows,cols as arrays for efficient usage latet on
di,dc = np.array([j[0]  for j in d]), np.array([j[1]  for j in d])

# Get col and index data
i,c = df.index.values.astype(di.dtype),df.columns.values.astype(dc.dtype)

# Locate row indexes from d back to df
I,badmask_I = ssidx(i,di)

# Locate column indexes from d back to df
C,badmask_C = ssidx(c,dc)

badmask = badmask_I | badmask_C

goodmask = ~badmask

df.values[I[goodmask],C[goodmask]] = newval

如果列表中有重复的元素,则此操作不起作用,因为生成的数据帧会重复这些行/列。我更新了我的示例。熊猫不是进行此类操作的最佳工具。根据您的描述,我认为您需要查看稀疏矩阵(scipy.Sparse)。我得到的错误
索引I超出轴0的范围,大小为I
,在
I=sidx\u I[np.searchsorted(I,di,sorter=sidx\u I)]
行。这可能意味着什么?@harrystat是否保证
d
中的所有字符串都来自df的索引和列?嗯,不,不一定。@harrystat那么,该如何处理这种情况呢?分配时是否应跳过d中的元组?@HarryStudio添加了一个通用解决方案。
def ssidx(i,di):
    sidx_i = i.argsort()
    idx_i = np.searchsorted(i,di,sorter=sidx_i)
    invalid_mask = idx_i==len(sidx_i)
    idx_i[invalid_mask] = 0
    I = sidx_i[idx_i]    
    invalid_mask |= i[I]!=di
    return I,invalid_mask

# Get d-rows,cols as arrays for efficient usage latet on
di,dc = np.array([j[0]  for j in d]), np.array([j[1]  for j in d])

# Get col and index data
i,c = df.index.values.astype(di.dtype),df.columns.values.astype(dc.dtype)

# Locate row indexes from d back to df
I,badmask_I = ssidx(i,di)

# Locate column indexes from d back to df
C,badmask_C = ssidx(c,dc)

badmask = badmask_I | badmask_C

goodmask = ~badmask

df.values[I[goodmask],C[goodmask]] = newval