使用两个for循环和if条件在Python中填充数据框。

4
我可以为您进行翻译。以下是您需要翻译的内容:

我有两个数据框,其中一个看起来像这样:

df1:

x    y    Counts
a    b    1
a    c    3
b    c    2
c    d    1

另一个数据表的索引和列都是第一二列唯一数值列表:
df2
   a  b  c  d
a
b
c
d

我想做的是用第一个 DataFrame 的值填充第二个 DataFrame,给定列和索引的交集是来自第一个 DataFrame 的相同行,例如:
   a    b   c   d
a   0   1   3   0
b   1   0   2   0
c   3   2   0   1
d   0   0   1   0

当我尝试使用双重if条件的两个for循环时,电脑会发生阻塞(假设实际的DataFrame包含超过1000行)。

我试图实现的代码(计算量太大,电脑无法处理):

for i in df2.index:
    for j in df2.columns:
        if (i==df1.x.any() and j==df1.y.any()):
            df2.loc[i,j]=df1.Counts

请注意,唯一值列表(即第二个数据框中的索引和列)比第一个列中的行数要长。在我的例子中它们重合了。
如果相关的话,第一个数据框基本上代表了文本中第一列和第二列单词的组合及它们的出现次数。出现次数基本上是边的权重。
所以,我想创建一个矩阵来通过igraph绘制一个图形。我选择先创建一个DataFrame,然后将其值作为一个数组传递给igraph。
据我所知,python-igraph无法使用dataframe绘制图形,只能使用numpy数组。
尝试了一些类似问题的解决方案,但目前还没有成功。
欢迎任何改进我的问题的建议(这是我在这里的第一个问题)。
2个回答

5
你可以像这样做:
import pandas as pd

#df = pd.read_clipboard()
#df2 = df.copy()
df3=df2.pivot(index='x',columns='y',values='Counts')
print df3
print
new=sorted((set(df3.columns.tolist()+df3.index.tolist())))
df3 = df3.reindex(new,columns=new).fillna(0).applymap(int)
print df3

输出:

y    b    c    d
x               
a  1.0  3.0  NaN
b  NaN  2.0  NaN
c  NaN  NaN  1.0

y  a  b  c  d
x            
a  0  1  3  0
b  0  0  2  0
c  0  0  0  1
d  0  0  0  0

你知道口罩上的蓝色是干什么用的吗?我也有同样的问题,不知道是什么。 :-) - piRSquared
@piRSquared 是的,蓝色部分应该适合脸部(正如名字所示:Blue on the Face),但有点大。如果你试图戴上它,最好的贴合位置是灰色锥形的尖边应该在鼻子中央。点击面罩,拖动并重叠到一些面部上。 - Mohammad Yusuf
谢谢你,Mohammed!它确实起作用了,但是这个解决方案(pivot)让我“丢失”了一些我不应该丢失的值,例如列中的'a'和行中的'd'。虽然这些值以另一种方式存在(整个数据框将是对称的),但我必须有一个正方形矩阵。我想手动添加“缺失”的行和列,但再次需要太多时间。 - NellyM
@NellyM,piRSquared的解决方案适合您。只需用零填充NaN即可。 - Mohammad Yusuf
@NellyM 修改了我的解决方案。请检查它是否适用于您。 - Mohammad Yusuf
它确实有效,并且对于“小”示例和超过1200行和列的数据框都完美地工作。谢谢@Mohammad Yusuf Ghazi和@piRSquared!你们提出了多么优雅的解决方案! - NellyM

3

使用 df1 来填充 stackdf2 的缺失值。

idx = pd.Index(np.unique(df1[['x', 'y']]))
df2 = pd.DataFrame(index=idx, columns=idx)

df2.stack(dropna=False).fillna(df1.set_index(['x', 'y']).Counts) \
    .unstack().fillna(0).astype(int)

   a  b  c  d
a  0  1  3  0
b  0  0  2  0
c  0  0  0  1
d  0  0  0  0

1
顺便说一下,这很棒。我无法在脑海中解析你刚才做的事情。也许我会打印出来看看所有的部分。 :) - Mohammad Yusuf
谢谢你,@piRSquared!看起来正是我需要的,但实际上我得到的是整个DataFrame都填满了NaN值。在真实数据集上检查了两次,然后尝试了一个“小”的例子,即4行和列,结果我又得到了所有的NaN值。无法弄清楚我错过了什么。 - NellyM
@piRSquared 请检查我的解决方案。目前它可以工作,但如果x和y在原始数据框中没有排序,它会失败吗? - Mohammad Yusuf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接