Python 根据行索引值对数据帧列中的值求和
我有一个NxN数据帧。每一行对应于作为其索引的特定url(不带“http://”)。每一列还表示url,带有布尔值,指示此页面(行索引)是否链接到该页面(列名)。URL在索引和列中是相同的Python 根据行索引值对数据帧列中的值求和,python,pandas,filtering,Python,Pandas,Filtering,我有一个NxN数据帧。每一行对应于作为其索引的特定url(不带“http://”)。每一列还表示url,带有布尔值,指示此页面(行索引)是否链接到该页面(列名)。URL在索引和列中是相同的 In [1]: import pandas as pd In [2]: from pandas import DataFrame In [3]: df = DataFrame({'domain1.com/url1':[True,False,False,True,False],'domain2.com/u
In [1]: import pandas as pd
In [2]: from pandas import DataFrame
In [3]: df = DataFrame({'domain1.com/url1':[True,False,False,True,False],'domain2.com/url2':[False,True,False,True,True],'domain1.com/url3':[False,False,False,True,False],'domain3.com/url4':[False,True,False,True,False],'domain2.com/url5':[False,True,False,True,True]}, index=['domain1.com/url1','domain2.com/url2','domain1.com/url3','domain3.com/url4','domain2.com/url5'])
In [4]: df
Out[4]:
domain1.com/url1 domain1.com/url3 domain2.com/url2 \
domain1.com/url1 True False False
domain2.com/url2 False False True
domain1.com/url3 False False False
domain3.com/url4 True True True
domain2.com/url5 False False True
domain2.com/url5 domain3.com/url4
domain1.com/url1 False False
domain2.com/url2 True True
domain1.com/url3 False False
domain3.com/url4 True True
domain2.com/url5 True False
例如,现在我可以计算每个url的传入和传出链接:
In [5]: in_links_count = df.sum(axis=0)
In [6]: in_links_count
Out[6]:
domain1.com/url1 2
domain1.com/url3 1
domain2.com/url2 3
domain2.com/url5 3
domain3.com/url4 2
dtype: int64
In [7]: out_links_count = df.sum(axis=1)
In [8]: out_links_count
Out[8]:
domain1.com/url1 1
domain2.com/url2 3
domain1.com/url3 0
domain3.com/url4 5
domain2.com/url5 2
dtype: int64
到目前为止还不错。但如果我只想计算其他域的传入和传出链接,该怎么办?我想我需要以某种方式逐行过滤列。我尝试了诸如转置数据帧(以便排除列)和过滤之类的方法,但失败了:
In [9]: df_t = df.T
In [10]: df_t[ filter(lambda x: x.split('/')[0] != df_t.index.map(lambda x: x.split('/')[0]), list(df_t)) ].sum(axis=0)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-10-279439127551> in <module>()
----> 1 df_t[ filter(lambda x: x.split('/')[0] != df_t.index.map(lambda x: x.split('/')[0]), list(df_t)) ].sum(axis=0)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
[9]中的df\u t=df.t
在[10]:df_t[filter(lambda x:x.split('/')[0]!=df_t.index.map(lambda x:x.split('/')[0]),list(df_t))]和(axis=0)
---------------------------------------------------------------------------
ValueError回溯(最近一次调用上次)
在()
---->1 df_t[filter(lambda x:x.split('/')[0]!=df_t.index.map(lambda x:x.split('/')[0]),list(df_t))]和(axis=0)
ValueError:包含多个元素的数组的真值不明确。使用a.any()或a.all()
有什么想法吗,伙计们
UPD:
@piRSquared提供了一种解决方案,通过层次索引(stack()、index.to_series()、轴之间的差异、缺失数据的“假”值生成第二个数据帧(见下文);这在中等大小的数据中工作良好。然而,对于一个大的NxN数据帧(1000x1000),这肯定是一种过分的杀伤力。是否还有其他方法,或许可以利用就地筛选/映射?创建一系列索引/列对。过滤掉那些相同的域,并用
False
重新填充。然后将axis1和添加到axis0和
def domain(x):
return x.str.extract(r'([^/]+)', expand=False)
dfi = df.stack().index.to_series().apply(lambda x: pd.Series(x, ['u1', 'u2']))
keep = domain(dfi.u1) != domain(dfi.u2)
df1 = df.stack().ix[keep].unstack().fillna(False)
df1.sum(0) + df1.sum(1)
domain1.com/url1 1
domain1.com/url3 1
domain2.com/url2 2
domain2.com/url5 1
domain3.com/url4 5
dtype: int64
不太喜欢熊猫,但还是。。。可以迭代元素
In [40]: def same_domain(url1, url2):
return url1.split('/')[0] == url2.split('/')[0]
In [41]: def clear_inner_links(df):
for r in df.index:
for c in df.columns:
if(same_domain(r,c)):
df.loc[r,c] = False
return df
那就
df1.sum(0)
df1.sum(1)
基准:
In [35]: new_df.shape
Out[35]: (500, 500)
In [36]: %timeit clear_inner_links(new_df)
1 loop, best of 3: 956 ms per loop
更多方式:
In [102]: def same_domain(url1, url2):
.....: return url1.split('/')[0] == url2.split('/')[0]
.....:
In [103]: def apply_criterion(s):
.....: s[s.index.map(lambda x: same_domain(x,s.name))] = False
.....:
In [104]: def clear_inner_links2(df):
.....: df.apply(apply_criterion, axis=0)
.....: return df
.....:
In [105]: new_df.shape
Out[105]: (500, 500)
In [106]: %timeit clear_inner_links2(new_df)
1 loop, best of 3: 929 ms per loop
对于1000多个数据帧,第二种解决方案的性能比第一种(或piRSquared的约慢50倍)要好。但如果我只想计算其他域的传入和传出链接,该怎么办你能简要介绍一下这一点吗?我的意思是指向不同于url域的域的链接。感谢你提供一个好的、清晰的想法!您使用的是什么版本的pandas-i'm Get extract()有一个意外的关键字参数“expand”和AttributeError:“Series”对象在0.170.18.1中没有属性“extract”。去掉那个论点。我这样说是因为如果我不这样做,我会得到警告。你不需要它。在家里用一个大的DF尝试它,不幸的是,STACK()。