1

私のデータセットは、一緒に働いているか一人で働いている人々のリストです。

各プロジェクトの行と、そのプロジェクトに携わったすべての人の名前を含む列があります。列 2 が行の最初の空の列である場合、それは単独の仕事であり、列 4 が行の最初の空の列である場合、3 人が一緒に作業していたことになります。

私の目標は、どの人が何回一緒に働いたかを見つけることです。そのため、A が B と協力するのと同じように B が A と協力するのと同じように、データ セット内のすべてのペアが必要です。

これから、正方形 N x N が作成され、すべてのアクターが列と行にラベルを付け、セル (A,B) と (B,A) には、そのペアが一緒に働いた回数があり、これはすべてのペアに対して行われます。 .

私はExcelでそれを行うための「かなり」簡単な方法を知っていますが、プロジェクトが追加または削除された場合に備えて、再実行をワンクリックするだけで再実行する必要がないので、できればStataまたはPythonで自動化したいと思います毎回やってください。

コンマ区切り形式のデータの例:

A
A,B
B,C,E
B,F
D,F
A,B,C
D,B
E,C,B
X,D,A

それが役立つことを願っています!

ブライス。F,D B F F,X,C C,F,D

4

4 に答える 4

1

たぶん、このような何かがあなたを始めさせるでしょうか?

import csv
import collections
import itertools

grid = collections.Counter()

with open("connect.csv", "r", newline="") as fp:
    reader = csv.reader(fp)
    for line in reader:
        # clean empty names
        line = [name.strip() for name in line if name.strip()]
        # count single works
        if len(line) == 1:
            grid[line[0], line[0]] += 1
        # do pairwise counts
        for pair in itertools.combinations(line, 2):
            grid[pair] += 1
            grid[pair[::-1]] += 1

actors = sorted(set(pair[0] for pair in grid))

with open("connection_grid.csv", "w", newline="") as fp:
    writer = csv.writer(fp)
    writer.writerow([''] + actors)
    for actor in actors:
        line = [actor,] + [grid[actor, other] for other in actors]
        writer.writerow(line)

[編集: Python 3.2 で動作するように変更]

主要なモジュールは (1)csvです。これにより、csv ファイルの読み取りと書き込みがはるかに簡単になります。(2)collectionsと呼ばれるオブジェクトを提供しますCounter-- a のようにdefaultdict(int)、Python に がない場合に使用できます。これはCounter、デフォルト値を自動的に生成する辞書なので、必要はありません。ここでは、デフォルト カウントは 0 です。 ; (3)すべてのペアを取得itertoolsする機能があります。combinations

生産する

,A,B,C,D,E,F,X
A,1,2,1,1,0,0,1
B,2,1,3,1,2,1,0
C,1,3,0,1,2,2,1
D,1,1,1,0,0,3,1
E,0,2,2,0,0,0,0
F,0,1,2,3,0,1,1
X,1,0,1,1,0,1,0

を使用itertools.productして、アレイの構築をもう少しコンパクトにすることもできますが、1 ~ 2 行しかないので、手動で行うのと同じくらい簡単だと思いました。

于 2012-09-29T18:56:37.820 に答える
0

このプロジェクトをしばらく続けるとしたら、データベースを実装してから、そのデータベースに対するクエリから、あなたが話しているマトリックスを作成します。

プロジェクトごとに 1 つのレコードを含むProjectテーブル (たとえば)、Actor人物ごとに 1 つの行を含むParticipantテーブル、およびそのプロジェクトに参加していた各アクターのプロジェクトごとのレコードを含むテーブルがあります。(各レコードにはIDProjectID、および がありActorIDます。)

あなたの例から、14 個Projectのレコード、7個Actorのレコード (A から F、および X)、および 31個Participantのレコードがあります。

このセットアップでは、各セルはこのデータベースに対するクエリです。

マトリックスを再構築するには、まずデータベース内の適切なレコードを追加/更新/削除してから、クエリを再実行します。

于 2012-09-29T18:56:29.303 に答える
0

これらのプロジェクトで何千人もの人々が一緒に働いているわけではないと思います。この実装は非常に簡単です。

fp = open('projects.cvs')

# counts how many times each pair worked together
pairs = {}

# each element of `project` is a person
for project in (p[:-1].split(',') for p in fp):
    project.sort()

    # someone is alone here
    if len(project) == 1:
        continue

    # iterate over each pair 
    for i in range(len(project)):
        for j in range(i+1, len(project)):
            pair = (project[i], project[j])
            # increase `pairs` counter
            pairs[pair] = pairs.get(pair, 0) + 1

from pprint import pprint
pprint(pairs)

以下を出力します。

{('A', 'B'): 1,
 ('B', 'C'): 2,
 ('B', 'D'): 1,
 ('B', 'E'): 1,
 ('B', 'F'): 2,
 ('C', 'E'): 1,
 ('C', 'F'): 1,
 ('D', 'F'): 1}
于 2012-09-29T21:32:12.723 に答える
0

これにはPython Pandasを使用することをお勧めします。これにより、隣接行列をフォーマットするための洗練されたソリューションが可能になり、統計計算もはるかに簡単になります。値の行列をNumPy配列に直接抽出して、後で必要に応じてグループ クラスターで固有値分解やその他のグラフ理論手順を実行することもできます。

あなたがリストしたサンプルデータは、というファイルに保存されていると思いますprojects_data.csv(ただし、実際には .csv ファイルである必要はありません)。また、各観察の間に空白行がないことも想定していますが、これはすべてファイル編成の詳細にすぎません。

これが私のコードです:

# File I/O part
import itertools, pandas, numpy as np
with open("projects_data.csv") as tmp:
    lines = tmp.readlines()
lines = [line.split('\n')[0].split(',') for line in lines]
# Unique letters
s = set(list(itertools.chain(*lines)))


# Actual work.
df = pandas.DataFrame(
                      np.zeros((len(s),len(s))), 
                      columns=sorted(list(s)), 
                      index=sorted(list(s))
                     )

for line in lines:
    if len(line) == 1:
        df.ix[line[0],line[0]] += 1 # Single-person projects
    elif len(line) > 1:
        # Get all pairs in multi-person project.
        tmp_pairs = list(itertools.combinations(line, 2))

        # Append pair reversals to update (i,j) and (j,i) for each pair.
        tmp_pairs = tmp_pairs + [pair[::-1] for pair in tmp_pairs]
        for pair in tmp_pairs:
            df.ix[pair[0], pair[1]] +=1
            # Uncomment below if you don't want the list
            # comprehension method for getting the reverals.
            #df.ix[pair[1], pair[0]] +=1 

# Final product
print df.to_string()

   A  B  C  D  E  F  X
A  1  2  1  1  0  0  1
B  2  1  3  1  2  1  0
C  1  3  0  1  2  2  1
D  1  1  1  0  0  3  1
E  0  2  2  0  0  0  0
F  0  1  2  3  0  1  1
X  1  0  1  1  0  1  0

各参加者のプロジェクト パートナーの総数 (繰り返しを含む) を確認するなど、多くのことが無料でできるようになりました。

>>> df.sum()
A     6
B    10
C    10
D     7
E     4
F     8
X     4
于 2012-09-29T19:34:31.407 に答える