如何循環遍歷由 2 列創建的組中的行大家好,
我有一個非常簡單的問題,但無法從論壇找到確切的答案。 這是我的示例數據表:

基本上它有4 列,我需要循環遍歷從“組1”和“組2”生成的每個組合項目,但當且僅當“項目”# 不同時,然後打開“路徑”列中的所有文件路徑。 例如,在前 2 行中,我們的組合是“aA”,並且由於項目也不同,因此腳本需要打開文件路徑 1 和 2。
數據混合和清理回复:如何循環遍歷由 2 列創建的組中的行是的,這實際上非常有用。 file_list 變量很令人困惑,因為打開文件並不嚴格需要它(但是;我認為;它在稍後再次關閉所有文件時很有用(?),例如,或其他一些操作)。 我不得不承認,我也花了一些時間來理解“file_path”變量,該變量在每次迭代時都會分配給不同的文件路徑,並且它叫什麼並不重要。 (在我看來,我現在只是將其解釋為一種工具,從 filepaths_to_open 列表中依次選擇一個文件路徑,並讓用戶用它做“某事”。)
謝謝你! 每週增長一點點知識總比什麼都沒有好。
附: 下面我只能根據我對你的解釋的理解來寫。 再次強調,非常有用。
Names Default To Here( 1 );
filepaths_to_open = {"$SAMPLE_DATA/Big Class.jmp", "$SAMPLE_DATA/Probe.jmp", "$SAMPLE_DATA/Iris.jmp"};
For Each( {file_path}, filepaths_to_open, Open( file_path ) );
回复:如何循環遍歷由 2 列創建的組中的行我認為通過編寫演示腳本最容易理解這些(我對 For Each 進行了一些修改以添加 idx,這可能會讓它更容易理解它是如何工作的)
Names Default To Here(1);
filepaths_to_open = {"$SAMPLE_DATA/Big Class.jmp", "$SAMPLE_DATA/Probe.jmp", "$SAMPLE_DATA/Iris.jmp"};
show(filepaths_to_open);
file_list = {};
show(file_list);
For Each({file_path, idx}, filepaths_to_open,
show(idx, file_path);
Insert Into(file_list, Open(file_path));
show(file_list);
);
- 我使用 file_list 收集對打開的數據表的引用(我不需要文件路徑,因為我已經在 filepaths_to_open 中擁有它們,但我沒有引用)
- Open(file_path) 將返回對打開文件的引用,然後 Insert Into 將該引用添加到 file_list。
- {filepath} 來自如何對於每個功能應該使用。 基本上它將循環 filepaths_to_open 並返回 file_path 變量中的每個元素(一一)。
filepaths_to_open = {"$SAMPLE_DATA/Big Class.jmp", "$SAMPLE_DATA/Probe.jmp", "$SAMPLE_DATA/Iris.jmp"};
file_list = {};
idx = 1;
file_path = "$SAMPLE_DATA/Big Class.jmp";
file_list = {DataTable("Big Class")};
idx = 2;
file_path = "$SAMPLE_DATA/Probe.jmp";
file_list = {DataTable("Big Class"), DataTable("Probe")};
idx = 3;
file_path = "$SAMPLE_DATA/Iris.jmp";
file_list = {DataTable("Big Class"), DataTable("Probe"), DataTable("Iris")};
希望能回答一些問題。
回复:如何循環遍歷由 2 列創建的組中的行@jthi ,我只是想問幾個關於代碼最後部分的問題,即我不明白。
file_list = {};
For Each({file_path}, filepaths_to_open,
Insert Into(file_list, Open(file_path));
);
file_list = {};
這是一個空列表。 循環將通過 Insert Into(file_list, Open(file_path)) 填充此內容。 為什麼不能只使用 filepaths_to_open 中已包含的列表? 另外,我不明白 Open(file_path) 如何將某些內容插入列表中。 這不就是一個打開文件的函數嗎? 這一切如何才能對列表做出貢獻呢?
{file_path}這一點,我也想不明白。 這只是實際文件路徑的佔位符嗎?
也許你有解釋這些事情的參考資料? 預先非常感謝您。
回复:如何循環遍歷由 2 列創建的組中的行您將必須修改 ValidFile 計算,並可能修改行選擇,具體取決於構建 ValidFile 檢查的方式。
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
If(Col Sum(1, :g1, :g2, :i) == 1 & Col Number(:i, :g1, :g2) > 1,
1
,
0
);
));回复:如何循環遍歷由 2 列創建的組中的行@jthi ,一如既往的整潔。 好好學習,謝謝。
回复:如何循環遍歷由 2 列創建的組中的行我設法通過創建另一列“唯一”來找到一個:
new_col = dt << New Column("Unique", Numeric, Continuous, << Set Each Value(
Col Sum(1, :g1, :g2);
));
rows_to_open = dt << Get Rows Where(:ValidFile == 1 & :Unique != 1);
回复:如何循環遍歷由 2 列創建的組中的行謝謝jthi! 最後一個問題,如果這些列 g1、g2 和 i 只有 1 個有效文件的組合,我該如何進一步修改公式以忽略?

回复:如何循環遍歷由 2 列創建的組中的行編輯我的消息以重命名舊變量。 我們不是將字符列相加,而是通過分組 () 使用它們。 我們使用 1,因此組中的每一行都會增加 1。 通過使用這些函數創建不同類型的公式可能是一個好主意,以便更容易理解它們的工作原理,腳本索引還提供了一些示例。
Col Sum(名稱,<按變量, ...>)
回复:如何循環遍歷由 2 列創建的組中的行嗨,jthi,
感謝您提供如此精彩的答案,並提供了 3 個不同的選項。 附註之一是我必須從 rows_to_open1 變量中刪除“1”才能使代碼運行。 如果您能更正此拼寫錯誤以供將來參考,那就太好了!
除此之外,我還有一個與你的回答相關的問題。 Col Sum、Col Cumulative Sum 和 Col Max(Col Sum? 中的每一個中的值“1”的目的是什麼? 我不明白為什麼我們可以對 g1 和 g2 列中的字符值求和?
回复:如何循環遍歷由 2 列創建的組中的行嗨雷塞爾,
我已經嘗試過你的解決方案,確實打印了正如您提到的,“文件路徑6”兩次。 我看到的另一個問題是,當我故意將第 5 行項目值從 5 更改為 7 以獲得 2 個相同的行時,它會打印最後一行(“文件路徑 6”)。 有什麼辦法可以避免這種情況嗎? 我看到 jthi 的替代 for 循環也有同樣的問題。


回复:如何循環遍歷由 2 列創建的組中的行@雷塞爾
我認為重新考慮循環結構是最簡單的,但是您可以使當前的循環結構也按照您想要的方式工作,而無需重複打印:保留已打印內容的列表或找出某種附加邏輯來防止這種情況從發生。 我認為下面的想法應該可行:
For( i = 1, i <= N Items( PairedGroupList ), i++,
dt << Select Where( :PairedGroup == PairedGroupList[i] );
dtTemp = dt << Subset( Invisible, Selected Rows );
For( j = 1, j < N Rows( dtTemp ), j++,
If( dtTemp:item[j] != dtTemp:item[j + 1],
Print(dtTemp:path[j]);
If(j + 1 == N Rows( dtTemp ),
Print(dtTemp:path[j + 1]);
)
)
);
Close( dtTemp, no save );
);
例如,在這裡,您不會循環遍歷最後一個值,而是檢查下一個值是否是最後一個,如果是,則也打印該值(如果您確實打印了當前行)。
回复:如何循環遍歷由 2 列創建的組中的行我不確定我是否正確理解了問題,但下面是使用 Col Sum/Col Cumulative Sum 和 Col Max(ColSum()) 的三個不同選項
Names Default To Here(1);
dt = New Table("Untitled",
Add Rows(8),
Compress File When Saved(1),
New Column("g1", Character, "Nominal", Set Values({"a", "a", "a", "a", "a", "c", "c", "c"})),
New Column("g2", Character, "Nominal", Set Values({"A", "A", "B", "B", "B", "A", "A", "A"})),
New Column("i", Numeric, "Continuous", Format("Best", 12), Set Values([1, 3, 2, 4, 4, 5, 7, 9])),
New Column("p",
Character,
"Nominal",
Set Values({"filepath1", "filepath2", "filepath3", "filepath4", "filepath4.1", "filepath5", "filepath6", "filepath7"})
)
);
// depending how we handle duplicated g1+g2+i we would use different formulas
// if we won't open any
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
Col Sum(1, :g1, :g2, :i);
));
/*
// if we open the first one
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
Col Cumulative Sum(1, :g1, :g2, :i);
));
*/
/*
// if we don't open g1+g2 at all
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
Col Max(Col Sum(1, :g1, :g2, :i), :g1, :g2)
));
*/
rows_to_open = dt << Get Rows Where(:ValidFile == 1);
filepaths_to_open = dt[rows_to_open, "p"];
show(filepaths_to_open);
// dt << Delete Column(new_col);
// To open files loop over filepaths_to_open
stop();
file_list = {};
For Each({file_path}, filepaths_to_open,
Insert Into(file_list, Open(file_path));
);

想法是,我們選擇 ValidFile 為 1 的行,然後打開這些文件。 該圖演示了三個不同公式的計算。
編輯:
修復了舊參考要打開的行1到要打開的行數
回复:如何循環遍歷由 2 列創建的組中的行請研究 NChooseK Matrix() 並看看它是否適合您。在腳本索引中,它被描述為: 創建一個由 nChooseK(n,k) 行和 K 列組成的矩陣,形成從 1 到 n 的 k 個整數的所有組合。
我想知道是否可以將其更改為使用字符數據類型?
Names Default To Here( 1 );
Print( NChooseK Matrix( 5, 3 ) );
__________________________
Prints:
[ 1 2 3,
1 2 4,
1 2 5,
1 3 4,
1 3 5,
1 4 5,
2 3 4,
2 3 5,
2 4 5,
3 4 5]
回复:如何循環遍歷由 2 列創建的組中的行嗨,下面至少開始了你想做的事情。 您只需更改“打印( dtTemp:路徑[j], dtTemp:路徑[j + 1] )"部分具有打開文件的功能。
然而不幸的是,按照我編寫的方式,該腳本將“文件路徑 6”打印兩次到日誌中,因此如果進行相應修改,它也會打開“文件路徑6”兩次。 我確信有一種解決方法(例如檢查文件路徑是否已打開),但現在已經晚了。 不管怎樣,如果我也弄清楚如何做剩下的事情,我會讓你知道的。 感謝您的反饋!
dt = New Table( "today's challenge",
Add Rows( 7 ),
New Column( "group1",
Character,
"Nominal",
Set Values( {"a", "a", "a", "a", "c", "c", "c"} )
),
New Column( "group2",
Character,
"Nominal",
Set Values( {"A", "A", "B", "B", "A", "A", "A"} ),
Set Display Width( 70 )
),
New Column( "item",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Values( [1, 3, 2, 4, 5, 7, 9] )
),
New Column( "path",
Character,
"Nominal",
Set Selected,
Set Values(
{"file path 1", "file path 2", "file path 3", "file path 4",
"file path 5", "file path 6", "file path 7"}
)
)
);
dt << New Column( "PairedGroup", formula( :group1 || :group2 ) );
PairedGroupList = Associative Array( dt:PairedGroup ) << Get Keys;
dt << Clear Column Selection;
For( i = 1, i <= N Items( PairedGroupList ), i++,
dt << Select Where( :PairedGroup == PairedGroupList[i] );
dtTemp = dt << Subset( Invisible, Selected Rows );
For( j = 1, j <= N Rows( dtTemp ), j++,
If( dtTemp:item[j] != dtTemp:item[j + 1],
Print( dtTemp:path[j], dtTemp:path[j + 1] )
)
);
Close( dtTemp, no save );
);